为什么Git rebase会逐个回放特性分支提交?

9

我是一个新手,刚开始学习git命令,最近学到了git rebase命令。对于为什么git rebase命令会逐个重放功能分支的提交记录而不是只重放最新提交记录,我产生了疑问。

以下是我在项目中遇到的情况:

M1 --- M2 --- M3 --- M4
       |
       M2 --- F1 --- F2 --- F3

我们有4名开发人员参与了项目,我从上游/主分支的M2点派生了该项目。 我开始开发我的功能并添加了提交。 提交F1是一些基本代码。 然后提交F2是对提交F1进行的一些错误修复,类似地,提交F3是对提交F2中的代码进行的错误修复,而F3是我最终准备好的功能代码。
同时,其他开发人员完成了他们的功能,并将其代码合并到上游/主分支中。 现在我必须把我的代码放在他们的功能之上,即M4。 下面部分是我对git rebase的理解,我可能错了:
我检出了功能分支并使用upstream/master进行了git rebase,这种方式将我的功能分支放在M4之上,并开始逐个重播我的提交(F1,F2和F3)。 我在F1重放时遇到了冲突,并解决了它们。 因为F2是对F1的错误修复,所以我在同一位置再次遇到了类似的冲突,并再次解决了它们。 最后,当F3被重播时,我再次在同一位置遇到了类似的冲突。 我解决了冲突,一切正常。
但是,如果git尝试仅将我的功能分支的最后一个提交放在M4之上,则只需要解决一次冲突。 [因为我的F3代码也会包含F1和F2的代码]。 所以为什么需要这些额外的重播。
我可能遗漏了一些基本概念,请在我思考错误的地方纠正我。 谢谢!

这就是rebase的工作原理。你要找的是git merge。只需在主分支上检出,然后执行git merge {yourbranch}即可。 - Raul Rene
你必须将提交视为引入文件更改的内容(查看补丁是什么),然后你会理解要获取所有提交的更改,必须逐个应用每个提交引入的更改(而变基是应用所有提交补丁的过程)。 - Philippe
2个回答

4

为了只需一次解决冲突,您需要告诉Git将除了最后一次提交之外的所有提交压缩成一次。

要做到这一点,当你的功能分支被检出时,在M4之上启动交互式重组:

git rebase -i M4

您将看到一个可编辑的代码片段,类似于以下内容:
pick 111111 F1
pick 222222 F2
pick 333333 F3

您需要编辑此代码片段,以便告诉Git将F2F3压缩到F1中,从而创建一个代表自您分支以来所有更改的单个提交:

pick 111111 F1
squash 222222 F2
squash 222222 F3

F1被指定为要压缩到的提交,因为这就是命令的工作方式(即将更改融合到以前的提交中)。

保存这些编辑,退出片段,然后您只需要执行一步冲突解决。

请记住,在压缩F2F3时,您已经失去了那些明确的更改集。如果您想保留它们,则没有替代方法,必须在每个重放步骤上解决冲突。


1

Rebase的核心思想是将一个提交一个提交地应用到另一个提交之上。

来自文档:

然后,这些提交会一个接一个地重新应用到当前分支。

因此,Rebase实际上是将一个提交一个接一个地合并到前一个提交之上。现在,将其与你可以在Git中进行的其他类型的合并进行比较和对比:

git checkout master
git merge feature
merge 命令恰好满足您的要求:它将应用与 feature 分支中的 最新提交 相关联的所有累积更改,叠加在 master 中的 最新提交 之上,以单个操作完成。这意味着您只需解决所有冲突一次。
合并操作通常会在目标分支上创建一个 合并提交;合并提交的目的是将两条(或多条!)历史线连接起来。因此,虽然常规提交只有一个 父节点,但合并提交自然引用了 多个父节点
M1 --- M2 --- M3 --- M4 --- MF
       |                    |
       M2 --- F1 --- F2 --- F3

现在,合并操作不一定要导致合并提交。如果您希望(这可能是您想要的),您可以将发生在不同分支中的更改合并为一个单独的提交。
您可以创建所谓的压缩合并来实现这一点:
git checkout master
git merge feature --squash

这里的区别在于将从masterfeature合并的更改记录在master的顶部的单个提交中,导致历史记录看起来像这样:
M1 --- M2 --- M3 --- M4 --- MF
       |                    
       M2 --- F1 --- F2 --- F3

MF 包含了从 M4F3 合并的所有变更,并解决了所有冲突。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接