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

使用不同的树结构合并从一个回购到另一个回购的更改

  •  11
  • RavenHursT  · 技术社区  · 11 年前

    我有两个Git repo,foo/master和bar/master:

    在foo中:

    code_root
    ->dirA
      ->dirB
        -> *some files*
    

    条形图中:

    code_root
      -> *same files as above*
    

    现在有人对 *some files* …如何将这些更改合并到 *same files as above* ?

    当我说“合并”时,我的意思是我也需要增量的历史记录(提交消息、日志散列等)。

    3 回复  |  直到 11 年前
        1
  •  4
  •   johnb003    11 年前

    您可以将更改拆分到子树级别,然后与其他分支合并:

    # from your foo project
    git subtree split --prefix=dirA/dirB/ --branch=temp-branch [--onto=<onto-sub-note1>] [<commit-sub-note2>]
    

    到子注释1 :好像从那以后 酒吧 项目确实存在,您必须在某个时间点复制了它,并将其作为新库启动,在这种情况下,如果您希望在此之后进行所有更改,您可以指定 酒吧 引入更改时提交id。

    提交子注释2 :然后,您需要指定在第一次复制子项目时使用的提交id,以便您只获得此后的更改以合并到 酒吧 你已经有了(这将保持你错过的历史)。使用如下语法包含最新的提交id: 0abc210^..

    您也可以使用 --rejoin 向您的 食品 项目,如果您想继续开发,这将使以后更容易进行更改 酒吧 在您的 食品 项目重新提交到 食品 除了帮助子树命令库之外,它在将来更容易进行拆分更改,这是一种毫无意义的做法。

    运行split命令后,您将进入 食品 ,其中只有这些文件。从那里,您可以使用 酒吧 项目或启动新项目并合并 酒吧 (因为它可能没有合适的历史)。但是,在尝试进行合并之前,您可能需要重新调整到分叉点或其他位置。

    编辑:这里还有 reference for git subtree commands

        2
  •  1
  •   brokenfoot    11 年前

    所以,你是说foo&bar,只是foo中的那些比bar中的那些更新:

    如果是,那么你可以做一个比较:

    diff -b /path_to/foo/dirA/dirB/ /path_to/bar/ > diff.patch
    

    然后将贴片贴到条上:

    cd bar
    
    patch -p1 < diff.patch
    

    更新:根据更新的OP,他希望维护提交历史记录,在这种情况下,上述内容将不起作用。

        3
  •  1
  •   vonbrand    11 年前

    查看 git book git magic 。取决于具体的变化,也许是一轮历史改写( git filter-branch 和朋友;或暴力应用 git rebase --interactive ,纠正每个提交)可以恢复损坏的克隆的正常性,然后允许进行干净的合并。

    另一种选择是将每个提交导出为补丁(本质上是运行 git format-patch ),从那里恢复提交数据,并对要应用的修补程序进行反向工程。在这样做的时候,你甚至可以利用这个机会改写一个更干净/更简单的历史。

    显然,可行性取决于分歧的程度,以及有多少“错误应用”的承诺受到威胁。