我想了解为什么rebase要更改顺序和提交ID。请考虑以下提交树:
F1 -- F2 feature
/
M1 -- M2 -- M3 main
还有一个团队正在执行对main的更改,并将其推送到远程,我需要从main到feature的最新更改,因此我决定使用rebase如下:
myrepo git:(main) git pull origin main
现在,我的本地main
分支包含来自远程(M3)的最新更改。现在,我需要转到特性中,并做一个git重基:
➜ myrepo git:(main) git checkout feature
Switched to branch 'feature'
Your branch is up to date with 'origin/feature'.
➜ myrepo git:(feature) git rebase main
Successfully rebased and updated refs/heads/feature.
检查我的提交历史记录:
d78c8d5 (HEAD -> feature) F3
775e06c F2
1cc4843 F1
31a5870 (origin/main, origin/HEAD, main) M3
9fd7263 M2
756c88d M1
eec81ba Initial commit
结果是预期的,因为重基把所有的功能提交“后”主要提交。问题是,如果我在没有任何参数的情况下运行rebase,如下所示:
➜ myrepo git:(feature) git rebase
warning: skipped previously applied commit 1cc4843
warning: skipped previously applied commit 775e06c
hint: use --reapply-cherry-picks to include skipped commits
hint: Disable this message with "git config advice.skippedCherryPicks false"
Successfully rebased and updated refs/heads/feature.
除了表示将跳过先前应用的提交的警告消息外,它还真正更改了顺序并提交ID:
65ed33d (HEAD -> feature) F3
2b7e517 M3
7cea741 (origin/feature) F2
9c267ef F1
9fd7263 M2
756c88d M1
eec81ba Initial commit
这似乎与上游有关,因为现在可以在不使用--force
选项的情况下运行push。
➜ myrepo git:(feature) git push
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 10 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (7/7), 641 bytes | 641.00 KiB/s, done.
Total 7 (delta 1), reused 0 (delta 0), pack-reused 0
remote:
remote: To create a merge request for feature, visit:
这究竟是什么“第二次重新基地”,没有争议做什么?为什么要更改提交?“
发布于 2022-06-18 17:31:31
每个重基操作将采取任何未在目标上存在的提交,并在那里重新创建它们。我说的是重新创建,而不是移动,因为提交是不可变的,具有固定的更改集、父级、消息和其他元数据。重基是使用相同的消息、更改、元数据创建一个新的提交,但具有不同的父级。
现在,我将将origin/feature
添加到原始图中,指向F2,因为这是您的最终日志显示的位置。
我还将把F3
添加到原始图中,并假定feature
指向它。在重基之后显示的日志是不可能的,除非是这样。(还是在第一个重基之后创建了F3?在任何情况下,您都会在重基的结果中显示它,因此它必须是最初创建的,或者是在第二次重基之前创建的,但是根据您上一次日志输出,源文件/特性从未指向它。)
更新的初始状态:
F3 feature
/
F1 -- F2 origin/feature
/
M1 -- M2 -- M3 main, origin/main
第一个重基创建了F1‘、F2’和F3',并将feature
设置为指向F3‘,但只留下origin/feature
,仍然指向F2:
F1 -- F2 origin/feature
/
/ F1' -- F2' -- F3' feature
/ /
M1 -- M2 -- M3 main, origin/main
第二个重基表示以feature
为例,并将其重新基于origin/feature
之上。这意味着取M3,F1',F2‘和F3’,并在F2之后添加它们。M2处于共享历史中,因此不需要考虑它。现在,默认情况下,这可能会创建M1 - M2 - F1 - F2 - M3‘- F1’- F2‘-F3’作为feature
的新历史记录,但重基注意到F1‘与F1’具有相同的更改设置,因此它跳过它(如日志消息所述),对于F2‘也是如此。当您跳过创建F1'‘和F2’‘时,您得到的最终结果与预期的一样:
M3' -- F3'' -- feature
/
F1 -- F2 origin/feature
/
/ F1' -- F2' -- F3' (nothing points here anymore, but it still exists)
/ /
M1 -- M2 -- M3 main, origin/main
(原始的F3也仍然存在,F2是它的父级,但是没有分支指向它。不过,我的图表太拥挤了,无法显示。)
现在,如果您已经使用--keep-empty
运行了第二个重基,它告诉重基“保留不更改其父母的任何内容的提交”,那么您确实可以得到F1 - F2 - M3‘- F1’- F2‘-F3’,但是F1‘和F2’将是空提交,因为它们试图复制F1‘和F2’,这些都带来了在历史上已经应用到M3之前的变化。
https://stackoverflow.com/questions/72665250
复制相似问题