是否可以合并从同一个CVS源导入的不相交的Git repos?

时间:2015-07-23 08:50:42

标签: git

我有许多回购,这些回购是过去由不同个人执行的CVS导入。

所有这些repos都具有与CVS中相同的提交历史记录,并返回到CVS中的相同初始提交但是,尽管提交的内容相同,但提交ID不同。后来的提交有所不同,因为每个提交都有不同的变化,但它们的祖先是相同的,并追溯到同一个初始提交。

我已将所有这些回购信息整合到一个新的回购中。看着分支(用gitk)我可以看到它们都是不相交的,尽管有相同的变化历史。

我想要做的是以某种方式让git识别相同的提交,以便将历史记录合并到一个树中。这可能吗?

2 个答案:

答案 0 :(得分:3)

是的,这是可能的!而且,正如git一样,有几种方法可以做到。

您想要的是移植替换参考。以下是替换参考方式:

  • 使用git replace将所有重复的提交替换为&#34;规范&#34;版本。选择一个存储库的提交版本作为权威,然后重复git replace <other_repo_commit_hash> <primary_commit_hash>。当你这样做时,历史就会变得紧密相连。

以下是嫁接方式:

  • 创建名为.git/info/grafts的文本文件。在那里,每一行应该包含一个提交哈希,然后是一个空格,然后是一个空格分开的提交应该假装的父级列表。所以,如果你有两个&#34;相同&#34;提交,A和A&#39;,他们分别有孩子B和C,你想把C移植到A(给两个孩子,B和C)。您可以通过将C&C的提交哈希后跟A来放入移植文件中的一行来完成此操作。执行此操作时,存储库将如下所示:

          A ---- B
           \
            C
    
  • 请注意A&#39;离开了。在足够新版本的git中,您可以使用git replace --graft来获得类似移植的功能,尽管它实际上会在引擎盖下使用替换引用。

完成嫁接或创建替换参考后,您应该拥有一个连接历史记录,其中包含所有内容。现在,您希望在其上运行git filter-branch -- --all以使替换永久化。你不需要做任何真正的重写,尽管如果你愿意,你可以:只需运行filter-branch就可以使替换/移植物消失并留下无缝的历史记录。将生成的统一分支(但不是旧垃圾!)发送到新的git仓库并完成。

答案 1 :(得分:2)

感谢@Borealid这就是如何将具有相同历史的分支嫁接在一起。当历史记录具有不同的提交ID时,它可以工作。

首先,将条目写入文件.git/info/grafts。每行包含两个提交引用AB,其中A是要保留的分支中的第一个提交,B是其新父级。如果在我的情况下,每个分支都被移植到同一点,则所有条目都具有相同的B。我有两个这样的分支,我的文件看起来像这样:

209cbb0179ee490f4dbb7aaa6b7d7e32a1f4d21e 637bafd129d781516f9b1efbccd326484efecdb3
be007b20ac07770098701927730e01d965186b6e 637bafd129d781516f9b1efbccd326484efecdb3

现在,验证它在gitk --all中的显示效果。如果它已经运行,则点击<SHIFT><F5>重新加载。一旦您满意它看起来像预期的那样,继续使更改永久化:

$ git filter-branch -- --all
$ rm .git/info/grafts
$ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
$ git reflog expire --expire=now --all
$ git gc --prune=now

最后三个命令来自git filter-branch documentation