如何将两个(或更多)完全不相关的线性分支祖先“拼接”成一个新的?

时间:2014-09-19 07:49:54

标签: git merge branch

我试图将每个具有不同root提交的两个分支组合成一个新的空分支。这不是通常的合并事情,因为我不希望仅在最后一次提交中将分支组合在一起(在这种情况下,新分支将具有合并提交,并且'以下'仍然是两个单独的历史。新分支仍然有两个root提交。)。

我的场景中的一个重要事实是两个分支完全不相关。任何一个分支的提交都不会影响其他分支的路径。 commits =>没有冲突。

让我们假设以下分支:

A---B-----C-D
  X---Y-Z

这就是我要找的:

A-X-B-Y-Z-C-D

重点是我希望按时间顺序进行提交。 如何实现?

2 个答案:

答案 0 :(得分:5)

你写道:

  

我的场景中的一个重要事实是两个分支完全不相关。任何一个分支的提交都不会影响其他分支的补丁。 commits =>没有冲突。

当然,"拼接"如果你预计会出现很多冲突,你建议的操作可能是一个坏主意。让我们假设确实没有什么不好的事情发生。

如果在开始时,您的仓库看起来像这样

A---B------C--D [branch1]

  X---Y--Z [branch2]

您可以按照下面列出的步骤自动"拼接"从两个分支提交到一个分支,同时保持按时间顺序。

"拼接"两个不相关的分支

  1. 确保您处于干净的工作状态;然后查看branch1并将branch2合并到其中:

    git checkout branch1
    git merge branch2
    

    那将产生

    A---B------C--D---E [HEAD=branch1]
                     /
      X---Y--Z------- [branch2]
    

    现在,我知道这不是你想要的,而是忍受我一秒钟。我们将使用合并提交E来访问"双方的祖先"马上。

  2. 签出branch2并将其重置为提交A

    git checkout branch2
    git reset --hard A
    

    您将处于以下情况:

    A [HEAD=branch2]
     \
      ---B------C--D---E [branch1]
                      /
       X---Y--Z------- 
    
  3. 生成从branch1但不能从branch2到达的所有非合并提交的列表(按时间顺序排列):

    git rev-list --no-merges --reverse branch2..branch1
    

    这应该会产生以下提交列表:XBYZCD;在步骤1中创建的提交E将不在该列表中,因为我们使用了--no-merges标记。

  4. Cherry在branch2(A)之上挑选这些提交。

    git cherry-pick `git rev-list --no-merges --reverse branch2..branch1`
    

    您的回购将如下所示:

    A--X'--B'--Y'--Z'--C'--D' [HEAD=branch2]
     \
      ---B-----C-D---E [branch1]
                    /
       X---Y-Z------ 
    
  5. 删除branch1

    git branch -D branch1
    

    修改:正如您正确评论的那样,因为branch1未完全合并到当前分支(branch2),所以只使用-d赢了&#39}。在这里;你需要改为使用-D标志。

    您的回购将只是

    A--X'--B'--Y'--Z'--C'--D' [HEAD=branch2]
    
  6. (可选)重命名branch2

    git branch -m branch2 <more_meaningful_name>
    
  7. 对两个以上分支的推广

    假设您有n个完全不相关的分支:branch1branch2,...,branchn,其中branch1对应于其根的分支commit是整个存储库中最早的提交;让我们调用提交A

    A ----- o ---- o [branch1]
    
       o ----- o ---- o -- o [branch2]
    
    ...
    
     o ----- o - o [branchn]
    

    如果您不知道哪个提交是A,则可以通过运行

    来识别它
    git rev-list --reverse --max-parents=0 --all
    

    A的提交ID将是该命令输出中列出的第一个。您可以通过运行来确定哪个分支是branch1

    git branch -r --contains `git rev-list --reverse --max-parents=0 --all | head -1`
    

    然后,双分支案例中的程序概述变为:

    1. 通过将branch1以外的所有分支合并到branch1,创建一个可以访问所有分支的祖先的提交。

    2. (与双分支案例相同)

    3. (与双枝案相同)
    4. (与双枝案相同)
    5. 删除branch2以外的所有分支。
    6. (与双枝案相同)

答案 1 :(得分:0)

快速简单的合并解决方案是,

假设A --- B ----- C-D(是分支1)和X --- Y-Z(分支2)。 从branch-2(git format-patch -n)获取所有补丁,然后在分支1(git am * .patch)顶部应用所有补丁,然后随机播放你希望序列使用git rebase -i的地方HEAD〜n的

希望有所帮助!