如何将一个git分支拆分成两个分支?

68

我正在帮助一位同事解决问题,他不小心从另一个功能分支创建了一个功能分支,而不是从主分支创建第���个功能分支。现在我们大致有以下情况...

Master ---A---B---C
                   \
              Foo   E---F---F---H
                                 \
                            Bar   J---K---L---M

这就是我们想要的...

Master ---A---B---C
                  |\
             Foo  | E---F---F---H
                  |
             Bar  J---K---L---M

我想到的一种方法是创建FooV2和BarV2分支,然后将单独的提交挑选到相应的V2分支中。但我很好奇,是否有更好的处理这种情况的方法?

3个回答

144

为了提供一个更一般的答案,帮助我们更好地理解问题,而不仅仅是“运行这个命令”,我们需要一个更大的例子。因此,让我们假设您实际上处于以下情况:

---A---B---C <= Master
            \
             E---F---F---H <= Foo
                          \
                           J---K---L---M <= Bar
                                        \
                                         N---O---P---Q <= Baz

以下是我们想要的内容...

---A---B---C <= Master
           |\
           | E---F---F---H <= Foo
           |\
           | J---K---L---M <= Bar
            \
             N---O---P---Q <= Baz

幸运的是,Git在rebase命令选项中为我们提供了解决方案!

git rebase --onto [newParent] [oldParent] [branchToMove]

这意味着可以分解成以下几个部分:

  1. rebase - 改变某个东西的父级
  2. --onto - 这是告诉git使用此替代rebase语法的标志
  3. newParent - 这是你要重新定位其父级的分支
  4. oldParent - 这是分支当前所拥有的父级分支,你要忽略它在重定位中做出的更改
  5. branchToMove - 这是你正在移动(重新定位)的分支

关于“旧父级分支”的部分可能会有点混淆,但它实际上是在说“在进行rebase时忽略我的旧父级的更改”。 oldParent 是你定义你正在移动的分支(即branchToMove ) 开始的地方。

那么,在我们的情况下要执行哪些命令呢?

git rebase --onto Master Bar Baz
git rebase --onto Master Foo Bar

请注意这些命令的顺序很重要,因为我们需要从“分支链”的末尾拉出每个分支。


7
在最好的意义上,这让所有的魔力都消失了。我刚刚使用它来修复一个功能分支,在该分支上我对Foo做了一些工作,然后提交了一些关于Bar的提交,再加上一些Foo的提交,但都在同一次提交线上。#失败 - Ben Mosher
@BenMosher:我知道这是很久以前的事情了,但你是否成功地使用这种方法将 foo-bar-foo 转换为干净的 foo 和 bar? - Superole
2
@Superole:如果我没记错的话,我也用过 --onto 几次。 - Ben Mosher

21

我认为您可以:

git checkout J
git rebase master

编辑:

我尝试了我建议的方法,但没有起作用。knittl的建议在我的电脑上也没有效果。这是对我有效的方法:

git rebase --onto master foo bar

3
非常感谢,编辑后的版本效果很好!如果有人需要更多关于此事的细节,Pro Git书中有一个“更有趣的变基”章节,几乎涵盖了这个例子:http://git-scm.com/book/en/Git-Branching-Rebasing - Matt V.
8
git rebase --onto master foo bar 的意思是:将“bar”(不包含“foo”)移到“master”分支上。 - schoetbi
@schoetbi:你的评论在整个帖子中是VIP级别的。在看到它之前,我对任何答案都一无所知。 - Domi

7

您可以将Bar分支变基到主分支上:

git rebase --onto C H M

如果某些补丁冲突,您必须手动解决它们(但在挑选时也必须这样做)。警告一句:当历史记录已经发布时,请勿进行变基。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接