我们的仓库里有很多这样的提交记录:
Merge branch 'master' of bitbucket.org:user/repo
每当开发者将本地分支更新到顶层仓库时,就会发生这种情况。
有没有办法避免这些合并提交污染整个仓库的日志?在发起拉取请求时是否可以以某种方式避免它们?
我知道如果只是在本地虚拟机中完成,我可以使用 git rebase。 在 GitHub/BitBucket UI 中有类似的操作吗?
你们是如何处理这个问题的?
如果您想避免合并提交,您需要确保所有提交都是快进的。在合并之前,您可以通过确保您的功能分支在开发线上干净地重新定位来实现此目的,如下所示:
git checkout master
git checkout -b feature/foo
# make some commits
git rebase master
git checkout master
git merge --ff-only feature/foo
Rebase有很多标记,包括使用-i
标记进行交互式rebase,但是如果您尽可能保持简单,并希望在合并时保留所有分支历史记录,则可能不需要它。
--ff-only
标记除了rebase之外,使用--ff-only
标记将确保仅允许快进提交。如果提交将是一个合并提交,将不会进行提交。git-merge(1)手册页上说:
--ff-only
拒绝合并并退出非零状态,除非当前HEAD已经是最新的,或者合并可以解决为快进。
$ git branch
* master
您想进行修复,因此创建一个从主分支中分离出来的“fixbranch”分支。
$ git checkout -b fixbranch
也许您已经在这个分支上工作了几天,并提交了几次。
在您想要将提交推送到中央主存储库的那一天!请检出主分支并从中央主存储库获取最新更改
$ git checkout master
$ git pull origin master
将你的修复分支与主分支进行变基,以获得清晰的历史记录并在本地库中解决任何冲突。
$ git checkout fixbranch
$ git rebase master
现在fixbranch已经和中央master分支同步,让我将fixbranch合并到主分支中
$ git checkout master
$ git merge fixbranch
我完成了!让我将本地主分支推送到中央主分支。
$ git push origin master
Todd的回答涵盖了命令行。(--ff-only
,也可以配置为git命令行的默认合并策略。)
如果您使用GitLab,您是存储库的维护者,并且正在合并其他开发人员的合并请求。如果您想避免创建合并请求,请在存储库中打开“设置” ->“合并请求”,并强制执行仅快进合并:
这将仅在使用合并请求合并时防止合并提交。 如果您还使用命令行git merge
,则需要以上解决方案。
此设置的缺点是,如果有许多人在同一源上工作,则他们将不得不经常重建其功能分支,因为来自同事的更改将在他们之前合并。 但为了拥有良好的提交历史,这可能是一个小代价。
看起来怎么样?如果无法使用快速转发策略合并合并请求,则开发人员将在其合并请求页面上获得一个小的重新配置按钮:
他们可以通过单击按钮在 Web UI 中重新基于其特性分支,或者他们可以在命令行上进行变基并强制推送其特性分支到远程。这通常会触发另一个流水线再次构建和测试更改。
如果您使用 GitHub,那么就更简单了。首先,GitHub 尝试自动重新基于功能分支,只要拉取请求的目标分支更改即可。如果重新基础没有冲突,则无需手动操作。其次,如果您想避免创建合并提交,请使用下拉菜单中的最后一项执行合并,而不是直接单击按钮,以允许创建合并提交:
git pull
命令来将他们的特性分支与上游 (main
/master
/develop
) 更新,则会得到许多合并信息,例如 Merged 'develop' into
(回溯合并)。然后,当他们尝试最终合并到主分支时,可能会遇到错误,并且必须进行变基以满足此要求(如果他们的特性分支足够旧)。这样说对吗? - Guildensternpull --merge
命令。他们应该使用 pull --rebase
命令,然后将更改强制推送到远程分支。这样可以保持特性分支的历史记录清晰可读。 - Ferdinand Prantlpull --merge
命令。他们应该使用pull --rebase
命令,然后再使用push --force
命令推送到远程仓库。这样可以保持功能分支的历史记录清晰可读。 - Ferdinand Prantl可以实现以下操作:
以下是如何完成的:
from="branch2" // You only have to change this line
to=HEAD
first_shared_commit="$(
git merge-base "$to" "$from"
)"
list_of_commits_exclusively_in_from="$(
git log --format=%H "$first_shared_commit".."$from"
)"
git cherry-pick "$list_of_commits_exclusively_in_from"
我已经为此创建了一个别名。我称之为git merge-quiet
。您可以使用以下一行命令在您的.git/config
中创建此别名:
git config --global --add alias.merge-quiet '!f(){ to=HEAD; from="$1"; git cherry-pick $(git log --format=%H $(git merge-base "$to" "$from").."$from"); }; f'
我认为这是最好的解决方案,因为它不需要创建一个[暂时的]branch2-rebased分支来避免改变现有的branch2。它通过在内存中创建分支(实际上是将组成分支的提交列表)来实现。
欢迎您的反馈!☮️❤️☸️☯️