我正在尝试将一个功能分支(从master分支)重新定位到另一个分支的特定提交上。
我的初始状态是
C -- D branch1
/
A -- B -- E -- F master
\
branch2 (zero commits after creating the branch)
我先把布兰克2换成了一个能干的大师。根据我的理解,我现在的状态应该是
C -- D branch1
/
A -- B -- E -- F master
\
B -- E -- F branch2
我验证了branch2在commit a时分支到master,并且与master分支是平的。我现在想要的是这个
A -- B -- E -- F master
\
B -- E -- F branch2
\
C -- D branch1
我试过了
git checkout branch1
git rebase --onto B branch2
但这导致了一系列的冲突,我完全不明白这些是怎么产生的。也许我完全误解了瑞贝斯是做什么的?
注意:在成功地将branch1重设为branch2的b之后,我打算将master重设为a,所以最终版本应该如下所示。
A master
\
B -- E -- F branch2
\
C -- D branch1
最佳答案
你的假设有些问题。首先,分支只是提交的指针。从这里开始,master
被签出。
C -- D branch1
/
A -- B -- E -- F master
在你拿到这个之后。
C -- D branch1
/
A -- B -- E -- F master & branch2
注意这里没有存根分支,
git branch branch2
和master
都指向f。除了它们的名字,它们是不可区分的。一旦您签出
branch2
和branch2
就不会有任何变化。git rebase A
在它的祖先中已经有了branch2
,它仍然指向A
。你应该得到一条像F
这样的消息。当你做了这些混乱的事情。有一个假定的第三个参数,当前已签出的分支。你实际运行的是
Current branch branch2 is up to date
。也就是说“将branch1而不是branch 2(与git checkout branch1
或c和d相同)可以到达的提交放到b上”。这应该是一个禁止操作,但如果branch1和branch2有任何共同的变化,rebase会抛出它们。如果C和E做了同样的改变,你会因此而结束,很可能会发生冲突。
C -- D original branch1
/
A -- B -- E -- F master & branch2
\
D1 branch1
这没有多大意义,但当你试图在两个堂兄弟之间重新平衡时就会发生这种情况。
还要注意,重新定位的分支具有id d1,而不是d。commit id包含其父级的id,因此id必须更改。
git rebase --onto B branch2
不会重写历史,它会创建新的历史,并告诉您它一直是这样的。微妙但重要的区别。你原来的承诺还在…一段时间。如果你想离开这里:
C -- D branch1
/
A -- B -- E -- F master & branch2
为了这个。
A master
\
B -- E -- F branch2
\
C -- D branch1
你可以把它翻过来,这样它就和你更好的东西对齐了。
C -- D branch1
/
B -- E -- F branch2
/
A master
你只需要把
git rebase --onto B branch2 branch1
移到a。有几种方法可以做到,一种是git log branch2..branch1
。这迫使rebase
移动到master
。