为什么git rebase重播Feature分支一个提交一个?

时间:2019-04-17 07:52:47

标签: git github rebase

我是git命令的新手,最近遇到了git rebase命令。我有一个疑问,为什么git rebase命令会一一重播功能分支的提交,而不是只重播功能分支上的最新提交。

这是我在一个我正在工作的项目上的场景:

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

我们是4位开发人员,负责该项目,我在M2点从上游/主服务器分叉了该项目。

我开始使用我的功能并开始添加提交。提交F1带有一些基本代码。然后,提交F2是针对提交F1的一些错误修复,类似地,提交F3是针对F2处的代码的错误修复,而F3是我最终准备就绪的代码。

同时,其他开发人员完成了他们的功能,并将其代码合并到上游/主服务器中。现在,我必须将代码放在M4的功能之上。现在,以下部分是我对git rebase的理解,我可能是错的:

我签出了功能分支,并使用上游/主服务器进行了git rebase,这种操作将我的功能分支放在M4之上,并开始一个接一个地重放我的提交(F1,F2和F3)。我在F1重播时遇到冲突,并解决了这些冲突。由于F2是F1的错误修复,因此我在同一位置再次遇到了类似的冲突,并再次解决了这些冲突。最后,当重播F3时,我在同一位置再次遇到了类似的冲突。我解决了冲突,一切都很好。

但是,除了重播提交F1,F2,F3之外,如果git试图仅将功能分支的最后一个提交放在M4之上,那么我将只能解决冲突。 [因为我在F3中的代码也将具有F1和F2的代码]。那么为什么要这些额外的重播。

在这里我可能缺少一些基本概念,请在我做错想法的地方纠正我。谢谢!

2 个答案:

答案 0 :(得分:1)

您必须告诉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被提名为squash的提交,因为这是命令的工作方式(即,它将更改合并到上一个提交中)。

保存这些修改,退出代码段,您将只看到一个解决冲突的步骤。

请记住,挤压F2F3时,您已经丢失了这些明确的变更集。如果您希望保留它们,那么除了解决每个重放步骤中的冲突之外,别无选择。

答案 1 :(得分:0)

Rebase就是关于一次在另一个一个上应用提交。

来自documentation

  

然后将提交[...]依次一个接一个地重新应用到当前分支。

因此,变基实际上是在上一次提交的同时一次合并一次提交。现在,与您可以在Git中进行的other kind of merging进行比较和对比:

git checkout master
git merge feature

merge命令完全满足您的要求:它在顶部的feature分支中应用与最新提交相关的累积更改。 master中的>最新提交,只需一次操作。这意味着您只需解决所有冲突一次。

合并操作通常会导致在目标分支上创建合并提交;合并提交的目的是合并两个(或更多!)历史记录行。因此,尽管常规提交只具有一个父母,但合并提交自然会引用多个父母

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

现在,合并操作不一定必须导致合并提交。如果需要(这可能正是您要查找的内容),可以合并在不同分支中发生的更改,同时仍然创建一个提交。

您可以创建一个squash merge

git checkout master
git merge feature --squash

此处的区别在于,masterfeature的组合更改记录在master顶部的单次提交中,导致历史记录看起来像这样:

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

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