git rebase如何/为什么避免合并提交?

3 git git-merge git-rebase

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

Sch*_*ern 5

rebase不像合并分支那样进行合并。而是rebase一系列git cherry-pick。樱桃镐选择一个提交并将其复制,就好像它是在其他某个提交之上编写的一样。这就好比您将提交的差异应用到其他地方一样。

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

A - B - C - D [master]
         \
          E - F - G [feature]
Run Code Online (Sandbox Code Playgroud)

如果master需要E,也许这是一个关键的错误修复程序,但并非所有其他功能都feature可以git cherry-pick E。Git将以C为原点在D和E之间进行合并,从而得到E1。这就是为什么在重新设置基准时可能会发生合并冲突的原因。但是与普通合并不同,E1只有一个父级。

A - B - C - D - E1 [master]
         \
          E - F - G [feature]
Run Code Online (Sandbox Code Playgroud)

重新设置就像是否对所有提交都执行了。而且与其处于顶峰,master不如动摇feature。这是git rebase master逐步的样子。

再次考虑您的存储库。

A - B - C - D [master]
         \
          E - F - G [feature]
Run Code Online (Sandbox Code Playgroud)

首先,如前所述,它cherry-pick在E上执行一个操作,并将其放在上master。但是master,它没有移动,而是创建了一个没有标签的新分支。

              E1
             /
A - B - C - D [master]
         \
          E - F - G [feature]
Run Code Online (Sandbox Code Playgroud)

然后将其插入F并将其放在E1的顶部。

              E1 - F1
             /
A - B - C - D [master]
         \
          E - F - G [feature]
Run Code Online (Sandbox Code Playgroud)

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

              E1 - F1 - G1
             /
A - B - C - D [master]
         \
          E - F - G [feature]
Run Code Online (Sandbox Code Playgroud)

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

              E1 - F1 - G1 [feature]
             /
A - B - C - D [master]
         \
          E - F - G
Run Code Online (Sandbox Code Playgroud)

是的,旧的提交仍然存在。如果没有引用它们的信息(例如标签或其他分支),则将在几周内将其回收。同时,您仍然可以使用访问它们git reflog。有关更多信息,请参见Pro Git的“ 维护和数据恢复”一章

  • 如果不是合并,那为什么要指定合并策略呢?怎么可能在不是合并的东西上发生合并冲突?这适用于 `git rebase`。 (2认同)
  • “ git rebase”将您的提交变成一系列补丁是绝对不正确的,它根本不能那样工作,如果您以这种方式考虑,您会对“ git rebase”的工作方式感到惊讶。git rebase和git cherry-pick所做的是三向合并。它以这种方式工作的事实并不是可以掩饰的内部细节,这对`git rebase`的工作方式至关重要,如果您尝试通过应用来复制`git rebase`或`git cherry-pick'的行为,一连串的补丁程序您将遇到问题。 (2认同)

bre*_*hin 2

您可以这样想:git rebase从您的分支中获取新的提交并将其放在一边,然后倒回您的分支以匹配更新的原始分支,最后将您的提交添加到结果之上;git merge只需创建一个新的(合并)提交,其中包含分支之间的差异。请注意,在重新设置原始分支上不存在的所有提交的情况下,它们的哈希值将发生变化,因此您将不得不强制推送新分支(如果有多个人在同一个分支上协作,这并不总是那么容易)分支)。然而,变基可以让您避免合并提交并保持更清晰的历史记录。