我为什么要做git rebase?

时间:2012-11-02 10:51:57

标签: git git-rebase

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

看起来像是一个费用,回过头来修改你的提交历史(肯定会涉及与n路冲突的一些丑陋的合并)。我可以想象它可能会产生误导的情况(例如,如果两个人以不同的方式解决同样的问题,但历史并没有表明他们的工作是平行发生的;似乎很容易导致批评和怨恨在某些高压编码环境中)。

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

提前致谢。

3 个答案:

答案 0 :(得分:8)

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

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

在典型的共享开发树中,每个开发人员都会通过执行git pull; <resolve conflicts>; git push的某些变体来推送到共享分支。如果他们使用git pull而没有--rebase,那么几乎每个提交最终伴随着合并提交,即使没有真正进行并行开发。这创造了一个交织的历史,从实际上是一个线性的提交序列。出于这个原因,git pull --rebase对于由于短期开发而导致的小变化是更好的选择,而合并则保留用于集成长寿命的功能分支。

所有这些都适用于重新定位本地提交,或者重新绑定由密切相关的同事(坐在同一个房间)共享的短期功能分支。一旦提交被定期推送到分支机构,然后由其他人提交,它应该从不被重新定位。

答案 1 :(得分:3)

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

与大多数与git相关的事情一样,如果你知道你正在做什么,那么你应该只进行改变,而为什么你正在做什么。以下是我进行变基的一些原因:

  • 我已经开发了一个补丁系列,但在此期间没有触及任何已在上游被改变的组件。在这种情况下,合并提交不包含任何有用的信息。
  • 我即将在GitHub上提交拉取请求,并且需要合并提交将需要很多工作。通过首先进行变基,我使上拉所有者更容易处理拉取请求。当然我可以合并,但因为他们以前从未见过我的代码,这只会让补丁系列难以阅读。
  • 我正在合并来自上游的变化,并且存在大量冲突。 git rebase让我一次解决这些提交中的冲突,让我更容易理解,并随时进行测试。如果我关心维护合并提交,我可以稍后回到分支的非重定版版本,将其与上游合并,然后在针对合并提交的冲突时使用针对重定版版本的差异。

答案 2 :(得分:0)

TLDR:Rebase 策略不值得付出努力。

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

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

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

但是这里是重新定位策略的成本

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

这两种方法我都试过了,当我比较利弊时,Rebase 策略不值得一试。