如何从一个重新分支的分支机构中重新分支?

Rad*_*zea 34 git branch rebase git-rebase

所以我的历史看起来像这样:

o---o---o---o master \ o---o---o A \ o B

所以,解释一下:

  • 我有A从哪个分支开始master
  • 我有一个分支B(只有1个提交)从哪个开始A

我想要的是这个:

o---o---o---o master \ o---o---o A \ o B


我做的是:

1).

git checkout A git rebase master

这导致了许多冲突,经过一段时间的修复后,出现了以下历史:

o---o---o---o master \ o---o---o A

这正是我想要的.

(我不知道B现在在哪里)


2).

在此之后我做了很多南瓜并改变了提交的顺序A,使历史看起来像我想要的.


3).

现在,我还想做的是:

git checkout B git rebase A

然而,这似乎不起作用,我不知道为什么.如果我这样做,git log我会在执行第1步之前看到那些提交.

此外,我得到了我在步骤1中已经解决的大量冲突.我花了很多时间去做,不想再这样做了.

这个例子建议使用--onto,我做了:

git checkout B git rebase --onto A

但是这会B完全删除提交,AB指向同一个提交,即最后一个提交A.


我的问题是:我怎样才能有效地将B关闭A以使其看起来像B从A开始?(这在开始时实际上是真的).

我最好的猜测是我使用--onto错了.或者我应该使用别的东西(比如cherry-pick).

Tho*_*s F 39

简短回答我怎样才能有效地将B关闭A以使其看起来像B从A开始? 假设您想要移动一个提交:

git rebase --onto A B~ B
Run Code Online (Sandbox Code Playgroud)

如果你想移动多个提交使用:

git rebase --onto A old_A B
Run Code Online (Sandbox Code Playgroud)

其余的答案.

你的B分支仍然存在(你可以检查出来),但它的父代仍然A是以前的确切提交对象.
看到我使用的图形表示:

git log --graph --decorate --all
Run Code Online (Sandbox Code Playgroud)

查看所有分支机构以及它们彼此之间的位置.

你原来有什么:

o---o---o---o  master
     \
      o---o---o  A
               \
                o B
Run Code Online (Sandbox Code Playgroud)

你现在拥有的:

o---o---o-----------o  master
     \               \
      o---o---o(B~)   o---o---o A
               \
                o B
Run Code Online (Sandbox Code Playgroud)

在使用方面--onto,您需要有一个起点和一个终点.使用:

git rebase --onto [target] [rebasing stops] [rebasing head]
git rebase --onto A B~ B
Run Code Online (Sandbox Code Playgroud)

你得到了什么:

o---o---o----------o  master
     \              \
      o---o---o      o---o---o A
            (old_A)           \
                               o B
Run Code Online (Sandbox Code Playgroud)

[branch_name]~ 表示分支的父提交.

B~是你不想改变的分支.(它恰好是旧的A)

或者,如果B是唯一一个将A作为父级的提交,(即,B是从master分支的提交链的末尾),你可以做

git checkout B
git rebase master
git checkout B~   # this is the commit before B (the A commit)
git branch -d A   # remove the old A branch (it was rebased, and so is now invalid
git branch A      # recreate the A branch on the commit that is based on the original A
Run Code Online (Sandbox Code Playgroud)

  • 注意那些盲目的复制粘贴(就像我做的那样):第二个参数需要指向`old A`,所以`B~`只有在`B`有一个提交时才有效 - 在这里,它确实有效.我喜欢将语法看作`git rebase --onto <new base> <old base> <head>`; `<old base>`是`<head>`当前分支的地方,`<new base>`是你希望它从哪里分支的地方. (9认同)
  • 谢谢。`git rebase --onto AB~ B` 工作**完美**。现在我要弄清楚的是为什么:) :D (2认同)

Tim*_*Lin 10

我在git flow中也遇到了同样的问题,并且我找到了一种最佳且快速的方法。

(1)一开始的项目历史:

    master ---A---B---C
                \
                 D---E---F feature1
                          \
                           G---H feature2
Run Code Online (Sandbox Code Playgroud)

(2)将feature1重新设置到master上并强制按下:

    master ---A---B------------------------C
                \                           \
                 D---E---F feature1(old)     D---E---F feature1
                          \
                           G---H feature2
Run Code Online (Sandbox Code Playgroud)

(3)将feature2重新基础到featrue1(新的featrue1)上

    master ---A---B------------------------C
                                            \
                                             D---E---F feature1
                                                      \
                                                       G---H feature2
Run Code Online (Sandbox Code Playgroud)

最困惑的部分是如何做(3) ..但是没有人对这样做有明确的答案。

我相信许多人都遇到了和我一样的问题,当我们尝试“重新设置--onto”时,我们发现feature1(old)实际上不存在!

    git rebase --onto feature1 feature1(old) feature2
Run Code Online (Sandbox Code Playgroud)

解决方法是改用下面的方法:

    git rebase --onto feature1 feature1@{1} feature2
Run Code Online (Sandbox Code Playgroud)

语法feature1 @ {1}的意思是“ rebase之前feature1的最后一个已知状态”,答案参见https://coderwall.com/p/xzsr9g/rebasing-dependent-branches-with-git