Git pull 创建了不需要的合并提交

Rob*_*bin 5 git

当我将工作提交到分支A并推送到存储库时,git 抱怨我需要更新我的项目。我通过更新了我的项目git pull,并完成了自动合并。现在合并后有两次提交:一次提交是我的更改,另一次提交来自git pull.

我注意到合并提交已经包含了已反映在存储库中的所有更改,那么当所有更改都已反映时,为什么 git 专门为该合并创建另一个提交呢?有没有办法在推送之前删除该合并提交?它使事情变得不必要的复杂化。该合并提交本质上是无用的。

r3m*_*n0x 6

为了避免在拉取时创建冗余合并提交,您应该使用git pull --rebase. 您也可以在当前情况下执行它以摆脱合并提交。

  • 如果您有 30 次提交,并且您进行了变基并在第一次提交时遇到了重大冲突,那么您可能必须解决其余 29 次提交的冲突...一次...在...a。 ..当...时间。我喜欢良好的 rebase,但有时合并是最明智的做法。 (2认同)

Mar*_*ger 6

合并会将您的本地更改与从服务器获取的更改合并在一起。如果您没有本地更改,或者没有从服务器获取新更改,则不会创建合并提交。这可能是也可能不是您想要反映更改集成的方式 - 您可以通过配置或命令行选项设置其他选项 - 但它确实必须以某种方式发生。

特别是,我的意思是 - 您指出存储库中的所有更改都已在没有合并提交的情况下得到考虑。但是必须有从远程获取的提交,这些提交尚未在本地存储库中 - 否则将不会有合并提交。如果您绘制合并提交的历史记录,您应该看到类似的内容

             R -- S
            /      \
x -- x -- O -- A -- M
Run Code Online (Sandbox Code Playgroud)

其中A是您的本地提交,O是您之前从远程获取的提交, 和RS您拉取时从远程获取的提交(也基于O)。您可以M通过 (a) 检查RS或 (b)diff对照来了解正在M执行的操作A

(一种可能令人困惑的特殊情况,服务器更改的最终R结果可能是“无更改”。例如,也许有人提交了,但随后将其恢复R并提交为S。生成的合并将没有效果,但 git 仍然必须这样做是为了确保分支仅在每次推送时向前移动。)

无论如何,这是默认行为,因为这是将远程更改合并到本地分支的最简单、最安全的方法。但这不是唯一的方法。您可以要求 git 将rebase本地分支转移到远程分支。然后你会得到

x -- x -- O -- R -- S -- A'
Run Code Online (Sandbox Code Playgroud)

对于简单的工作流程,这是合理的,并且它往往符合变基的最大规则——(大致)它避免重写已经共享的提交。

但它确实有成本和风险。来自https://git-scm.com/docs/git-config下的文档pull.rebase

注意:这是一个可能存在危险的操作;除非您了解其含义,否则请勿使用它(有关详细信息,请参阅 git-rebase [1])。

您的提交被替换为A',它尚未通过任何单元测试。仅此一点还不算太糟糕 - 在“合并”情况下,M也尚未通过任何测试。但是,如果您有更复杂的本地历史记录,则许多提交可能会被重写。因此,您最终可能会得到许多未经测试的提交,而推送未经测试的提交可能会让以后的生活变得更加困难(例如,如果您想用来bisect查找引入错误的提交)。

此外,可能需要进一步配置来确定应如何处理本地历史记录中的合并提交。

尽管如此,对于某些工作流程(例如,如果您经常拉取并期望不会有大量或复杂的本地历史记录),收益可能会超过成本;在这种情况下你可以

git pull --rebase
Run Code Online (Sandbox Code Playgroud)

或者将其设置为默认值

git config pull.rebase true
Run Code Online (Sandbox Code Playgroud)