我正在尝试将一个功能分支(从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 branch2master都指向f。除了它们的名字,它们是不可区分的。
一旦您签出branch2branch2就不会有任何变化。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

08-26 20:58