17

我见过很多人谈论git rebase它以及它的作用,例如Hg: How to do a rebase like git's rebase并且人们谈论它实现了什么(给出线性历史),例如这里Git rebase 失去了历史,那么为什么要 rebase?但我无法理解你为什么要这样做。

返回并修改您的提交历史似乎是一笔巨大的开支(这肯定涉及一些丑陋的合并与 n 路冲突)。而且我可以想象它可能会非常误导的情况,(例如,如果两个人以不同的方式解决同一个问题,但历史并没有显示他们的工作是并行发生的;似乎也很容易引起批评和怨恨在一些高压编码环境中)。

您获得的是更容易理解但不正确的历史图表。是什么让这值得付出努力?

提前致谢。

4

3 回答 3

15

Rebase 在推送单个提交或在短时间内(几小时或几分钟)开发的少量提交时最有用。

在推送到共享服务器之前,必须首先拉取同时提交到源的 HEAD 的提交——否则将创建非快进推送。这样做时,可以在合并 ( git pull) 或变基 ( git pull --rebase) 操作之间进行选择。合并选项虽然在技术上更具吸引力,但会创建额外的合并提交。对于小提交,每次更改出现两次提交实际上会降低历史可读性,因为合并操作会分散提交消息的注意力。

在典型的共享开发树中,每个开发人员最终都会通过对git pull; <resolve conflicts>; git push. 如果他们使用git pullwithout --rebase,则会发生几乎每个提交最终都伴随着一个合并提交,即使没有真正进行并行开发。这从实际上是线性提交序列中创建了一个相互交织的历史。出于这个原因,对于git pull --rebase短期开发导致的小更改是一个更好的选择,而合并则保留用于集成长期存在的功能分支。

所有这些都适用于 rebase本地提交,或 rebase 由紧密联系的同事(坐在同一个房间)共享的短期功能分支。一旦提交被定期推送到其他分支,就永远不应该重新设置它。

于 2012-11-02T11:01:42.060 回答
4

执行变基通常不涉及比合并更多的冲突解决,因此与之相比的费用是最小的(实际上只是重播提交所需的时间)。

与大多数与 git 相关的事情一样,只有在知道自己在做什么以及为什么要这样做的情况下,才应该重新设置基准。以下是我重新定位的一些原因:

  • 我一直在开发一个补丁系列,它没有触及任何同时在上游改变的组件。在这种情况下,合并提交不会包含任何有用的信息。
  • 我即将在GitHub 上提交拉取请求,所需的合并提交将是很多工作。通过首先变基,我使上游所有者更容易处理拉取请求。当然我可以合并,但由于他们以前从未见过我的代码,这只会使补丁系列更难阅读。
  • 我正在合并来自上游的更改,并且存在大量冲突。git rebase让我在提交时一次解决这些冲突,使其更容易理解,并在我进行时进行测试。如果我关心维护合并提交,我可以在之后返回到分支的非重新定位版本,将其与上游合并,然后使用针对重新定位版本的差异作为冲突解决合并提交。
于 2012-11-02T11:12:30.233 回答
1

TLDR:变基策略不值得努力。

变基策略的唯一好处是线性历史,仅此而已。

现在问自己一个问题,你检查了多少次 git 历史来找出一些东西?你能用合并策略解决它吗?

我的回答几乎是从不,是的,合并策略不是很好,但已经足够好了。

但这里是变基策略的成本

  • 每次其他人将更改推送到主分支时,您都必须重新调整您的更改,这对 3 个开发人员来说很好,但对于更多开发人员来说,这会成为一个问题,添加到它等待管道构建并且合并任何东西都会变得很恐怖。
  • 您一次只能将一个更改“合并”到主分支,所有其他更改必须首先重新设置基础并再次通过管道构建(额外延迟)。
  • 必须为每个提交单独解决冲突,如果我知道我在下一次提交中更改了它,那么解决旧/过时提交的冲突对我来说是疯狂的。
  • 如果你搞砸了 rebase,你会将所有修复添加到最后一次提交中,而所有旧的修复都会被破坏。另一种选择是重新开始一切。
  • 你必须在 rebase 后强制推送到你的分支,如果你把它搞砸了,你可能会花很长时间扫描 reflog。
  • 如果您的分支上有两个以上的提交,您可能会在变基之前将它们压缩以减少工作量,并且您会丢失宝贵的提交历史。

我都尝试过,当我比较利弊时,Rebase 策略不值得努力。

于 2021-03-19T10:57:33.400 回答