据我了解,提交是文件的快照,因此如果我执行更改A然后更改B,则更改B的提交文件已包含更改A中的更改,不会重新排序让变更多余?
答案 0 :(得分:5)
实际上,这是一个非常好的问题,因为提交是快照。
rebase工作的原因是因为rebase实际上是重复git cherry-pick
(在前面有一点包装以找出要选择的内容,最后更多地移动分支标签),{{1通过将提交转换为更改集。
假设您有这样的提交序列:
git cherry-pick
要将 A--B--C <-- topic
/
...--o--*--o--o <-- mainline
重新定位到topic
,我们需要(1)找到mainline
但不在topic
上的提交(mainline
, C
和B
沿着顶行,以标记为A
的提交结束),然后(2)将它们复制到我们将添加到{{1 }}
Rebase首先找到三个帖子*
提交并将它们放入(反向排序:mainline
,*
,A
)列表中(它也省略了合并提交)默认情况下,这里没有合并)。然后它为每次提交做一个樱桃选择。
要挑选B
,Git将C
与A
区别开来。这会将两个快照转换为更改集。然后,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 pick
,C
vs B
,A
vs {进行比较{1}})。