代码之家  ›  专栏  ›  技术社区  ›  alexandrul

如何合并没有共同祖先的两个分支?

  •  26
  • alexandrul  · 技术社区  · 17 年前

    我已经开始在我的项目中使用Git,其中前两个提交只是一些初始设置(.GiTigNo.G.ItAcess)和第三个提交。 平方米

    I1 -- I2 -- M2 -- N -- .. -- Z
    

    我已在名为的分支中导入了SVN历史记录 哪里 M1 ,除了.gitignore和.gitattributes):

    A -- B -- ... -- K -- L -- M1
    

    问: 合并两个分支的最佳方法是什么?

    我可以合并 M1 和 平方米 M3 I1 提交,如果我可以安全地删除 M3 M3

    A -- B -- ... -- K -- L -- M1
                                 \
                                  M3 -- N' -- .. -- Z'
                                 /
                   I1 -- I2 -- M2 -- N -- .. -- Z
    

    另一种方法是樱桃采摘 N Z 手动分支,但我希望避免这种方法。

    最优雅的解决方案是重新确定 .. Z svn

    3 回复  |  直到 17 年前
        1
  •  33
  •   Community Mohan Dere    9 年前

    免责声明 :

    你可以用“嫁接点”来伪造祖先信息。参见,例如。, What are .git/info/grafts for? 或立即前往 the git wiki entry on graft points

    本质上,您将创建一个文件 .git/info/grafts 这诱使git认为 是一个祖先的承诺 平方米 :

    $ cat .git/info/grafts
    <your M2 commit hash> <your M1 commit hash>
    

    平方米 I2 M1

    主要缺点 :未提交移植点;因此,它不会签出,但需要手动添加到存储库的每个本地工作副本中。



    更新: git replace --graft 相反

    git replace --graft <your M2 commit hash> <your M1 commit hash>
    

    .git/refs/replace/

    git push origin 'refs/replace/*'
    git fetch origin 'refs/replace/*:refs/replace/*'
    

    ( StackOverflow: How to push 'refs/replace' without pushing any other refs in git?

        2
  •  5
  •   Esko Luontola    15 年前

    尝试首先将I1和I2拾取到M1上,然后使用命令 git rebase --onto M1' M2 Z (其中M1'是M1-I1-I2分支)。我不确定在没有共同祖先的情况下,rebase-ON是否有效,但如果没有,就有可能使用补丁。使用 git format-patch git am 将其应用于M1之上。 Here are some experience reports 在转换旧的SVN和CVS存储库时使用它。

        3
  •  4
  •   wjandrea sebs    7 年前

    我会做以下几件事:

    git checkout M1
    git cherry-pick I1
    git cherry-pick I2
    

    这将为包含更好历史记录的分支添加.gitignore和.gitattributes。

    然后将新提交设置在该提交之上:

    git filter-branch --parent-filter 'if $GIT_COMMIT = $hash_of_N; then printf -- '-p
    $hash_of_cherrypicked_I2\n'; else cat; fi'
    

    the one for the Linux kernel