我是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的代码]。那么为什么要这些额外的重播。
在这里我可能缺少一些基本概念,请在我做错想法的地方纠正我。谢谢!
答案 0 :(得分:1)
您必须告诉Git压缩除最后一次提交以外的所有提交,以实现您只希望解决一次冲突的期望。
要执行此操作,请在您的功能分支检出时在M4
上启动交互式资源库:
git rebase -i M4
系统会为您提供类似于以下内容的可编辑代码段:
pick 111111 F1
pick 222222 F2
pick 333333 F3
然后,您将编辑此代码段,以告知Git将F2
和F3
压缩为F1
,从而产生一个提交,代表您分支以来的所有更改:
pick 111111 F1
squash 222222 F2
squash 222222 F3
F1
被提名为squash的提交,因为这是命令的工作方式(即,它将更改合并到上一个提交中)。
保存这些修改,退出代码段,您将只看到一个解决冲突的步骤。
请记住,挤压F2
和F3
时,您已经丢失了这些明确的变更集。如果您希望保留它们,那么除了解决每个重放步骤中的冲突之外,别无选择。
答案 1 :(得分:0)
Rebase就是关于一次在另一个一个上应用提交。
然后将提交[...]依次一个接一个地重新应用到当前分支。
因此,变基实际上是在上一次提交的同时一次合并一次提交。现在,与您可以在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
此处的区别在于,master
和feature
的组合更改记录在master
顶部的单次提交中,导致历史记录看起来像这样:
M1 --- M2 --- M3 --- M4 --- MF
|
M2 --- F1 --- F2 --- F3
MF
包含M4
和F3
的合并更改,并解决了所有冲突。