问题 如果它迫使你留在当地,为什么要使用rebase?


我很抱歉提出关于合并与rebase的哲学辩论,但我有一个实际的问题,关于典型的公司工作流程(不是开源项目工作流程,可能会有所不同)。

重新定位,如 这里指出,如果您推动了更改,则不应使用。这是如此,因为其他人可能已从你的分支分支,然后重写该分支的历史(通过强制推动)将使他们很难。

因此,使用变基的正确方法是仅在本地提交。但至少在我的简短经历中,这是不可取的:

  • 如果你的电脑被盗怎么办?
  • 如果由于磁盘故障导致数据丢失怎么办?
  • 如果你必须在两个地方工作(如 这个人

将功能分支保持在本地对我来说是违反直觉的。不仅由于以上几点,而且由于以下用例:您正在开发一项功能,但要么被拖到更紧急的地方,要么去度假,或生病。一位同事必须完成它。然后你改变和推动(除非你生病了,在这种情况下,它保持在本地,没有人可以完成它),而另一个人完成它。

在此期间,主人有变化。但另一个人已经基于一个远程分支,所以他应该使用merge,或rebase和force-push(如果其他人同时将其分支基于那个分支,那么这可能会使事情变得棘手)。

这听起来像边缘情况,但它们不是。这些条件中的至少一个(在家工作,生病,去度假,完成别人的工作等)经常发生。

那么,使用“rebase”是一种很好的方式进入这些用例,或者合并(使用额外的“merge commit”)是更安全,更直接的选择吗?


11167
2018-06-08 13:36


起源

拥有本地分支是DVCS中D的组成部分。 - Sten Muchow
您的功能分支不应该是其他人工作的基础。他们的工作基于未完成(未经审核,未经测试,可能会有变化)的代码。按照你的意愿推出你的功能分支和rebase是完全没问题的。 - jready


答案:


所以我倾向于支持变革。 Git图历史很重要。您希望它有一些关于功能分支的信息以及它们如何合并,但是一旦您有多个人,图表就会很快陷入混乱。通常,您希望了解过去几天发生的事情,图表的质量是能否从git图中获取信息之间的差异。

另外,请注意力推 功能分支 这不是什么大不了的事。强制推送的问题是你必须通过非git手段通知人们git活动 - 在Slack等上ping它们。这显然不适用于开源项目或具有多个贡献者的分支。但是大多数功能分支只有一个贡献者,因此他们可以根据需要强制推送。即使有两三个人正在处理它,你也可以通过强制推动来解决它 - 我们组织的典型情况是在打开拉取请求之前和合并之前。你偶尔会在工作过程中从上游获取一些东西,但通常你不需要,除非你想要。

当我们合并时,我们会做两件事 - 我们在最重要的时候 master 然后我们合并 --no-ff。这会创建一个带有空左路径的合并气泡,其中(1)组一起提交,(2)使直接进入主设备的提交脱颖而出(偶尔有效 - 修补程序,小改进,拼写错误,空格等)。

这种方法的警告是需要一段时间才能学习。你不能使用GitHub合并按钮(它不能达到我们的预期),你必须有足够的git chops来做一个rebase并注意图形。我见过的大多数开发人员都不在。每个新的团队成员需要花一点时间来解决这个问题,并且通常会将历史混乱一两次(我们有git hooks帮助)。但我发现这笔交易值得花时间。好处是:

  • 功能分支不是本地的。
  • 历史保持相当干净。
  • 主题提交通过合并气泡进行分组。
  • 强制推动通常不是问题,因为(1)它很少发生,(2)你要么独自工作,要么最多只能成对工作。

作为一个旁注,“不要把你已经推到原点的东西变废”对我来说总是听起来像一个新手规则。是的,当你不知道自己在做什么时,你可能会陷入困境。但是一旦你熟练掌握了git,就应该开始训练。


4
2018-06-09 08:46



这听起来像是一个明智的工作流程,虽然我有两个问题: - 使用强制推送作为工作流程的常规部分听起​​来并不像“Linus所期望的那样” - 这使得人们更难以分支WIP分支(这对我来说,是一个合法的用例)。但如果您关心图表,那就是要走的路。另一方面,如果不这样做,仅合并工作流程可以为您节省复杂性。 - Bozho
好吧,内核和它的开发人员团队是一个非常不同的野兽,而不是一个拥有产品驱动组织的中小型团队。皮肤猫的方法不止一种,git支持各种方法来满足不同的需求。 - Stefan Kanev


精确陈述的规则是:“不要改变可能成为另一个分支基础的分支”。通常,只有不发布您的分支才能轻松实现它 - 没有人看到它,所以没有人可以使用它。所以这就是为什么 “如果你推了就不应该使用”。但在某些情况下,它是可以接受的工作流程 - rebase / push / rebase / push / ...你只需要与他人达成一致意见,他们不会使用推送的分支来满足他们的需求,或者明确同意下一个改变/推动的rota (如果是生病/假期/等),或者你只是在几个地方工作(我希望你能在某些时候同意自己)。

顺便说一下,有一个 --force-with-lease 选择避免可能由推动的rebase引起的某些伤害。


5
2018-06-08 13:57



我同意。保持“脏”分支是完全没问题的 某处 非本地的,并反复强迫一个人在那里重新定位。我个人正是因为“备用”的原因而做的,因为这是一个很糟糕的手势。在准备“漂亮”历史之前,我最终将合并为一个“有福”的历史路线,我可能会有一个尴尬的分支,我推到像“tmp / branchname”这样的东西。 - kostix
使用force-push作为日常工作流程的一部分,听起来很奇怪。不是它不起作用,但仍然。而且我有多个人在我未完成的分支上建立分支的情况(并且用例是合法的,而不是hacky),这种情况对于rebase来说更难/更糟糕 - Bozho
@Bozho当然,有些情况下rebase更难,有些情况下更容易。您有权选择何时以及如何使用它。只需要知道它是如何工作的,如果某些东西没有达到预期效果就不会感到惊讶。 - kan
@Bozho我每天都会用力推几十次...... git bak (我做的一个琐碎的别名)我推送到我的个人备份分支(或者到另一个存储库;取决于项目)。每当我得到 任何 进步,我承诺(并经常“bak”)。显然,没有人希望每天获得数百次提交,这些提交必须变得更好。这并不妨碍以后合并好的提交,所以你可以同时拥有它们。 - maaartinus


您可以安全地使用rebase来更新本地分支 相同 远程跟踪分支(如git pull --rebase),而正如您所说,当您与其他协作者一起工作“共享”分支时,最好使用合并,而您不想重写远程历史记录(使用git push - 力)。

所以,根据你的git工作流程,由于git的分布式特性,如果你更喜欢rebase而不是merge,最好使用一个单独的分支(或者像一个单独的repo,比如github“forks”)来推送你的更改并最终合并它到目的地分支。


1
2018-06-08 13:58





我倾向于同意保守的规则,不要反对推动分支。正如其他答案所指出的,它不一定是问题所在 --force-with-lease 选项消除了很多痛苦。保守策略仍然有两个优点:

  • 它很容易记住,没有ifs和buts,你甚至可以通过禁止强制执行它 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 必须手动挑选他们在最新分支上的工作。


1
2018-06-08 14:17