Git rebase - 在fork-point模式下提交select

时间:2017-02-27 12:44:47

标签: git github version-control

阅读git rebasegit merge-base人员文档:

  

在使用git checkout -b topic origin / master创建的主题分支之后,远程跟踪分支origin / master的历史记录可能已被重绕并重建,从而导致了这个历史记录   形状:

                        o---B1
                       /
       ---o---o---B2--o---o---o---B (origin/master)
               \
                B3
                 \
                  Derived (topic)
     

其中origin / master用于指向提交B3,B2,B1,现在它指向B,并且当origin / master在B3时,您的主题分支在它之上启动。此模式使用reflog          origin / master找到B3作为分叉点,以便可以通过以下方式在更新的origin / master之上重新定位主题:

$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic

$fork_point将(如果我理解正确的话)是提交对象B3,因此提交B3..topic将被重新定位到origin/master分支。

Q1 为什么省略B3提交有用? topic分支的提交建立在B3提交之上,因此省略它将意味着在origin/master分支的故事中将缺少其修改。重新定位B3提交 topic分支会带来更清晰的历史,不会吗?

Q2 有人可以链接/简要描述git工作流程中--fork-point选项的实际用例吗?

1 个答案:

答案 0 :(得分:11)

{J} $fork_point {/ 1}}是正确的。

相信这里的意图是省略B3为"而不是你的提交"。

我认为Git人员在这里绘制的图表并不是那么好。这里是我如何在不改变它的情况下重绘和重写它(尽管我可能只是重写每个提交的内容)。

首先克隆(或以其他方式更新)某些(B3)存储库,其图表以commit origin结尾,然后创建一个主题分支并进行一些提交:

B3

随着时间的推移,使用额外的...--o---F---B3 <-- origin/master \ G <-- topic - es和git fetch,您的提交图现在看起来像这样:

git commit

但是,突然之间,在另一个 ...--o---F---B3--B2--B1 <-- origin/master \ G---H---I <-- topic 之后,您自己的提交图现在看起来像这样:

git fetch

也就是说,Git现在认为提交B3属于您的主题分支,实际上,您的工作始于提交 o---B1' <-- origin/foo / ...o---F---B2'-o---o---o---B <-- origin/master \ B3--G---H---I <-- topic 。拥有名为G的存储库的人实际上已声明提交origin很糟糕,应该被丢弃。 (他们在B3上保留了B2 B2'的副本,master上保留了B1 B1'之一。)

如果您只是foo,则会将原始提交git rebase复制到新副本B3(同时还要复制B3'):

G-H-I

但您宁愿选择:

                 o---B1'                     <-- origin/foo
                /
...o---F---B2'-o---o---o---B                 <-- origin/master
                            \
                             B3'-G'--H'--I'  <-- topic

o---B1' <-- origin/foo / ...o---F---B2'-o---o---o---B <-- origin/master \ G'--H'--I <-- topic 执行此操作,您必须指示Git找到提交git rebase。您的B3的reflog中包含所有origin/masterFB3B2(至少有一个reflog条目,包括本案例{ {1}}),同时您自己的B1还有origin/master@{1}topic,但F也不是B3。因此,B2选择B1作为最新(最尖端)共享提交,而不是--fork-point

这里的关键句子/想法是上游存储库编写者打算完全放弃提交B3

(你应该如何知道这一点有点神秘。如果需要重新定位,例如丢弃文件,FB3可能不是很明显应该永远不会被提交 - 并且在B2'中,这也是B1'也被丢弃的原因。现在B1B1中省略了这个文件这一事实非贴片等效,因此不是明显的副本。)

(请注意,您自己的B2'仍然指向B3'!)