用git合并不相交的分支

时间:2013-12-27 01:08:32

标签: git version-control merge

我目前的情况

我有2个相同软件项目的git存储库,其中一个是另一个的分支:

fork:                A1 - B1 - C1 - ... - HEAD_FORK
                      :
       (Some changes done outside of git)
                      :
orig: A2 - B2 - C2 - D2 - E2 - ... - HEAD_ORIGINAL

这两个历史是完全不相交的,它们没有共同的承诺。 (就git而言)

但是基于时间戳和我知道 fork 是从 orig 分叉的事实(不是使用VCS,而是通常的脏“只是复制文件和创建一个新的存储库“方式”我可以找到两者之间的“最小差异”点:

A1基于D2减去一些文件。

我的目标

合并这个烂摊子。我希望 fork 包含来自 orig 的所有有用的更改。

我不关心 orig 的历史。对 fork 的一次大型提交就可以了。 (无论如何,我可以分裂和重构)

我目前的战斗计划

我已经有一个git存储库,它包含两个历史记录作为分支。我打算做什么:

  1. 创建一个分支 orig-old ,其中D2是HEAD,分支 fork-old ,其中A1是HEAD。

    fork-old:                  A1 <- HEAD_FORK-OLD
                                :
                                :
    orig-old:   A2 - B2 - C2 - D2 <- HEAD_ORIG-OLD
    
  2. 合并 fork-old orig-old 创建 common-old

    fork-old:                  A1 <- HEAD_FORK-OLD
                                : \
    common-old:                 :  A3 <- HEAD_COMMON-OLD
                                : /
    orig-old:   A2 - B2 - C2 - D2 <- HEAD_ORIG-OLD
    
  3. common-old

    上的Rebase fork
    fork:                         B1 - C1 - D1 - .... - HEAD_FORK
                                  /
    common-old:                  A3 <- HEAD_COMMON-OLD
                                 /
    orig-old:    A2 - B2 - C2 - D2 <- HEAD_ORIG-OLD
    
  4. fork

    上的Rebase orig
    orig:                                E2 - F2 - ... - HEAD_ORIG
                                         /
    fork:         B1 - C1 - D1 - .... - X1 <- HEAD_FORK
                  /
    common-old:  A3 <- HEAD_COMMON-OLD
    
  5. 使用merge --squash合并重新定位的 orig fork

    orig:                         E2 - F2 - ... - K2 <- HEAD_ORIG
                                  /                \
    fork:  B1 - C1 - D1 - .... - X1 -------------- M1 <- HEAD_FORK
    
  6. fork M1的新HEAD和旧头(分叉存储库的HEAD)之间创建差异,并将其应用于分叉存储库。

  7. 我的问题

    这里有没有人尝试做类似的事情并且有经验可行吗? 由于我们在这里承担了相当大的工作(至少多天),所以在我开始合并所有这些之前知道我的计划是否疯狂会很高兴。

    我还考虑过只复制 orig 中的所有内容并将其粘贴到 fork 中的文件上 然后用“git add --patch”选择性地添加更改,但我认为这只会有很多复杂的变化。

    提前致谢!

1 个答案:

答案 0 :(得分:3)

这听起来像git-graft可能会有所帮助。基本上它允许您手动缝合历史记录。

以下是一些描述详细程序的文章: http://bugsquash.blogspot.com/2010/03/stitching-git-histories.html http://ben.straubnet.net/post/939181602/git-grafting-repositories

如果你添加一个移植物使A1成为D2的后代,git merge可以在其余的更改中合并一个可通过的作业。如果A1和D2之间存在实质性差异,您可以先{i}告诉git这些差异应该被视为合并,以便在您执行git merge -s ours A1

时不会妨碍这些差异

实际上,对于git merge HEAD_FORK,您可能根本不需要任何移植,因为假合并将加入两个分支的历史,但不是在历史的确切点。考虑到跨分支机构没有其他合并,不应该产生太大的影响。