为什么使用git rebase -i重新排序提交并不会搞砸历史?

时间:2016-04-29 22:49:13

标签: git

据我了解,提交是文件的快照,因此如果我执行更改A然后更改B,则更改B的提交文件已包含更改A中的更改,不会重新排序让变更多余?

1 个答案:

答案 0 :(得分:5)

实际上,这是一个非常好的问题,因为提交快照。

rebase工作的原因是因为rebase实际上是重复git cherry-pick(在前面有一点包装以找出要选择的内容,最后更多地移动分支标签),{{1通过将提交转换为更改集

假设您有这样的提交序列:

git cherry-pick

要将 A--B--C <-- topic / ...--o--*--o--o <-- mainline 重新定位到topic,我们需要(1)找到mainline但不在topic上的提交(mainlineCB沿着顶行,以标记为A的提交结束),然后(2)将它们复制到我们将添加到{{1 }}

Rebase首先找到三个帖子*提交并将它们放入(反向排序:mainline*A)列表中(它也省略了合并提交)默认情况下,这里没有合并)。然后它为每次提交做一个樱桃选择。

要挑选B,Git将CA区别开来。这会将两个快照转换为更改集。然后,Git将更改应用于A的提示最多提交,并在匿名分支上进行新提交,我们将其称为*

mainline

要挑选A',Git将 A--B--C <-- topic / ...--o--*--o--o <-- mainline \ A' <-- HEAD B区别开来。将这些更改应用于B会产生另一个提交A。重复A'以获取B'

C

最后,Git将C'标签从 A--B--C <-- topic / ...--o--*--o--o <-- mainline \ A'-B'-C' <-- HEAD 剥离,并将其指向topic。旧链被放弃(尽管您仍然可以通过reflog找到它,并且C也将C'的ID复制到特殊名称rebase

C

现在rebase已经完成。

请注意,如果需要,每个副本都使用git的合并机制完成(如果差异不能立即应用)。每一个都可能导致合并冲突,需要rebase停止并获得您的帮助。 (或者,更糟糕的是,你可能会误入歧途,尽管这些在实践中很少见。)

当然,如果您重新订购提交(通过在交互式rebase中移动ORIG_HEAD行),我们只需更改我们选择的顺序并应用每个提交。 cherry-pick操作仍然以相同的方式工作:将挑选的提交与其父级( A--B--C [abandoned] / ...--o--*--o--o <-- mainline \ A'-B'-C' <-- topic vs pickC vs BA vs {进行比较{1}})。