我很抱歉提出关于合并与rebase的哲学辩论,但我有一个实际问题,关于典型的公司工作流程(不是开源项目工作流程,可能会有所不同)。
如果您推送了更改,则不应使用pointed here重新绑定。这是如此,因为其他人可能已从你的分支分支,然后重写该分支的历史(通过强制推动)将使他们很难。
因此,使用变基的正确方法是仅在本地提交。但至少在我的短暂经历中,这是不可取的:
保留本地功能分支对我来说是违反直觉的。不仅由于以上几点,而且由于以下用例:您正在开发一项功能,但要么被拖到更紧急的地方,要么去度假,或者生病。一位同事必须完成它。然后你改变并推动(除非你生病了,在这种情况下它保持在本地,没有人可以完成它),而另一个人完成它。
在此期间,主人有变化。但另一个人已经基于一个远程分支,所以他应该使用merge,rebase和force-push(如果其他人同时将其分支基于那个分支,那么这可能会使事情变得棘手)。
这听起来像是边缘情况,但它们并非如此。这些条件中的至少一个(在家工作,生病,去度假,完成其他人的工作等)经常发生。
所以,正在使用" rebase"进入这些用例,或合并(使用附加"合并提交")的一种好方法是更安全,更直接的选择吗?
答案 0 :(得分:5)
准确陈述的规则是:“不要改变可能成为另一个分支基础的分支”。通常,只有不发布您的分支才能轻松实现它 - 没有人看到它,所以没有人可以使用它。所以这就是为什么“如果你已推”就不应该使用的原因。但在某些情况下,它是可以接受的工作流程 - rebase / push / rebase / push / ...你只需要与他人达成一致意见,他们不会使用推送的分支来满足他们的需求,或者明确同意下一个重新推销/推动的rota (如遇疾病/假期/等),或者您只是在多个地方工作(我希望您在某些时候能够同意自己的意见)。
顺便说一下,有一个--force-with-lease
选项可以避免可能由推送的rebase引起的一些伤害。
答案 1 :(得分:4)
所以我倾向于支持变基。 Git图历史很重要。您希望它拥有一些有关功能分支的信息以及它们如何合并,但是一旦您拥有多个人,图表就会很快陷入混乱。通常,您希望了解过去几天发生的事情,图表的质量是能否从git图中获取信息之间的差异。
另外,请注意强制推送功能分支并不是什么大不了的事。强制推送的问题是你必须通过非git手段通知人们git活动 - 在Slack等上ping它们。这显然不适用于开源项目或具有多个贡献者的分支。但是大多数功能分支只有一个贡献者,因此他们可以根据需要强制推送。即使有两三个人正在处理它,你也可以通过强制推动来解决它 - 我们组织的典型情况是在打开拉取请求之前和合并之前。你偶尔会在工作过程中从上游获取一些东西,但除非你想要,否则你通常不需要这样做。
当我们合并时,我们会做两件事 - 我们在master
之上重新定位,然后我们与--no-ff
合并。这会创建一个带有空左路径的合并气泡,其中(1)组一起提交,(2)使直接进入主设备的提交脱颖而出(偶尔有效 - 修补程序,小改进,拼写错误,空格等)。
这种方法的警告是需要一段时间才能学习。你不能使用GitHub合并按钮(它不能达到我们的预期),你必须有足够的git chops来做一个rebase并注意图形。我遇到的大多数开发人员都不在那里。每个新的团队成员都需要一段时间来解决这个问题,并且通常会将历史混乱一两次(我们有git hooks帮助)。但我发现这笔交易值得花时间。好处是:
作为一个旁注,“不要把你已经推到原点的东西变废”对我来说总是听起来像是一个新手规则。是的,当你不知道自己在做什么时,你可能会陷入困境。但是一旦你熟练掌握了git,现在是时候训练轮了。
答案 2 :(得分:1)
您可以安全地使用rebase从相同远程跟踪分支(例如git pull --rebase)更新本地分支,而正如您所说,当您使用合并时更好正在努力分享"共享"与其他合作者分支并且您不想重写远程历史记录(使用git push --force)。
所以,根据你的git工作流程,由于git的分布式特性,如果你更喜欢使用rebase而不是merge,最好使用一个单独的分支(或者像一个单独的repo,比如github" forks")推送您的更改,最后将其合并到目标分支。
答案 3 :(得分:1)
我倾向于同意保守的规则,即不要推销分支机构。正如其他答案所指出的,它不一定是个问题,--force-with-lease
选项消除了很多痛苦。保守策略仍有两个优点:
push --force
来强制执行它。然而,存在一种推动分支并仍然使用rebase的策略,即每次重写历史记录时只需创建一个新分支:
$ git checkout -b my_branch/WIP/01
... do some work, add some commits ...
$ git push
... notice that you want to clean up your history ...
$ git checkout -b my_branch/WIP/02
$ git rebase ...
$ git push
这样一来,如果有人依赖你之前发表的作品,那么它仍然存在,历史可以重复,并且不会涉及push --force
。
这种方法的缺点是, 在my_branch/WIP/01
工作的其他人必须手动挑选他们在最新分支上的工作。