首页 > 解决方案 > git rebase 如何/为什么避免合并提交?

问题描述

git rebase命令在后台使用合并,所以我想知道 a 如何/为什么git rebase避免合并提交,而 git merge 通常在分支之间存在差异时创建一个新提交。

标签: gitgit-mergegit-rebase

解决方案


rebase不像合并分支那样合并。相反,rebase是一系列git cherry-picks。樱桃选择接受一个提交并将其复制,就好像它是写在其他提交之上一样。就像您将提交的差异应用到其他地方一样。

考虑这样的存储库。A、B、C 等...代表提交 ID。

A - B - C - D [master]
         \
          E - F - G [feature]

如果master需要E,也许它是一个关键的错误修复,但不是其余的feature,它可以git cherry-pick E。Git 将以 C 作为原点在 D 和 E 之间进行合并,从而产生 E1。这就是为什么你可能会在 rebase 期间遇到合并冲突。但与正常的合并不同,E1 只有一个父级。

A - B - C - D - E1 [master]
         \
          E - F - G [feature]

变基就像对所有提交都这样做。而不是在它之上master移动feature。这是git rebase master一步一步的样子。

再次考虑您的存储库。

A - B - C - D [master]
         \
          E - F - G [feature]

首先,和以前一样,它cherry-pick在 E 上执行 a 并将其放在master. 但它没有移动master,而是创建了一个没有标签的新分支。

              E1
             /
A - B - C - D [master]
         \
          E - F - G [feature]

然后它会挑选 F 并将其放在 E1 的顶部。

              E1 - F1
             /
A - B - C - D [master]
         \
          E - F - G [feature]

然后它会挑选 G 并将其作为 G1 放在 F1 上。

              E1 - F1 - G1
             /
A - B - C - D [master]
         \
          E - F - G [feature]

随着樱桃采摘完成,它将feature分支标签移动到 G1。

              E1 - F1 - G1 [feature]
             /
A - B - C - D [master]
         \
          E - F - G

是的,旧的提交仍然存在。如果没有任何东西引用它们,比如标签或另一个分支,它们将在几周内被垃圾收集。同时,您仍然可以使用git reflog. 有关更多信息,请参阅 Pro Git 的维护和数据恢复一章


推荐阅读