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



当我将工作提交给分支A并推送到repo时,git抱怨我需要更新我的项目。我通过git pull更新了我的项目,并完成了自动合并。现在合并后有两个提交:一个提交用于我的更改,另一个提交来自git pull之后的自动合并。

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

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

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

特别是,我的意思是——你指出回购中的所有变化都已经在没有合并提交的情况下得到了考虑。但必须有从远程获取的提交,这些提交不在本地回购中——否则就不会有合并提交。如果你绘制合并提交的历史,你应该会看到类似的东西

R -- S
/      
x -- x -- O -- A -- M

其中,A是您的本地提交,O是您之前从远程获取的提交,而RS是您在提取时从远程获取(也基于O(的提交。您可以通过(a(检查RS,或(b(diffMA进行比较来了解M的作用。

(一个潜在的令人困惑的特殊情况是,服务器更改的net结果可能是"没有更改"。例如,可能有人提交了R,但随后还原了R并将其提交为S。由此产生的合并不会产生任何效果,但git仍然必须这样做,以确保分支只在每次推送时向前移动。(

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

x -- x -- O -- R -- S -- A'

对于简单的工作流来说,这是合理的,而且它往往符合重新定基的最大规则,即(大致(避免重写已经共享的提交。

不过,它确实有成本和风险。来自的文档https://git-scm.com/docs/git-configpull.rebase:下

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

您的提交被尚未通过任何单元测试的A'替换。仅此一点还不错——在"合并"的情况下,M还没有通过任何测试。但是,如果您有一个更复杂的本地历史,许多提交可能会被重写。因此,您最终可能会有许多未经测试的提交,而推动未经测试提交会使未来的生活更加艰难(例如,如果您想使用bisect来查找引入错误的提交(。

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

尽管如此,对于一些工作流程来说——比如,如果你经常拉车,并期望你不会有大量或复杂的当地历史——好处可能大于成本;在这种情况下,你可以选择

git pull --rebase

或者通过说将其设置为默认值

git config pull.rebase true

最新更新