将一个分支的顶级提交移动到另一个分支

时间:2018-06-08 09:30:44

标签: git

我想说我想从

开始
                    branch1 <- HEAD
                    ↓
A -- B -- C -- D -- E
     ↑
     branch2

          branch1
          ↓
A -- B -- C
      \-- D' -- E'
                ↑
                branch2 <- HED

当我在一个我应该承诺另一个分支的分支中提交时,就会发生这种情况。我还没有推动任何分支,所以我应该将DE提交从branch1移到branch2

如何将提交从一个分支移动到另一个分支?

一种可能性是挑选然后强行移动branche1,但这很难看:

git checkout branch2
git cherry-pick D E
git branch -f branch1 C

应该有可能的变种。

3 个答案:

答案 0 :(得分:1)

这正是rebase --onto的目的:你可以在任何提交的基础上重新分支一个分支。基本语法是:

git rebase --onto new_base old_base branch

在您的情况下,您必须先将branch2移至branch1

git checkout branch2
git reset --hard branch1

然后将branch2移到B的顶部:

git rebase --onto B C branch2

在此之后,您已将branch1移回C

git checkout branch1
git reset --hard C

详细示例:

  

命令行参数--onto可以传递给git rebase。在git中   rebase --onto模式命令扩展为:

git rebase --onto  
     

--onto命令启用更强大的表单或允许的rebase   通过特定的refs作为rebase的提示。

     

假设我们有一个带有分支的示例回购:

o---o---o---o---o master
                 \
                  o---o---o---o---o featureA
                   \
                    o---o---o featureB
     

featureB基于featureA,但我们发现featureB不是   取决于featureA中的任何更改,可能只是分支   master

git rebase --onto master featureA featureB
     

featureA<oldbase>master成为<newbase>featureB   是HEAD <newbase>所指的内容的参考。结果是   然后:

                  o---o---o featureB
                 /
o---o---o---o---o master
                 \
                  o---o---o---o---o featureA

(来自Atlassian Git Tutorial,搜索--onto

答案 1 :(得分:0)

您可以使用rebase交互式: git checkout branch1 git rebase branch2 -i HEAD~2

来源:https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History

然后,提交按您想要的顺序排列。如果要将分支移动到目标,则必须强制它们(git branch -f {branch-name} {postition}

答案 2 :(得分:0)

首先,请确保您没有未提交的更改。在其他任何事情之前提交或存储它们。

然后创建一个临时分支或指向提交E的标记。如果出现任何问题,您可以使用它(带结账和重置)来恢复branch1的位置并重新开始。达到预期结果后,您可以删除分支或标记。

您可以通过这种方式实现所需的结构:

# Make branch `branch2` point to commit `E`
git checkout branch2
git rebase branch1
# Move `branch1` onto its desired destination (2 commits behind its current position)
git checkout branch1
git reset --hard HEAD~2
# Get back to branch2
git checkout branch2
# Rebase its most recent 2 commits (D and E) on top of B
git rebase --onto HEAD~3 HEAD~2

或者,您可以将最后一个命令改为git rebase --onto branch1~1 branch1

它移动可从当前分支(branch2指向提交E)到达的提交但在提交branch1之上无法从分支branch1~1访问(branch1的父母)。这样,从branch1开始的历史记录行(branch1除外)将作为branch1的兄弟(或--onto的参数所在的位置)移动。

阅读documentation of git rebase,了解有关git rebase如何运作的更多信息。