如何连接两个git历史?

时间:2010-07-10 15:09:57

标签: git repository history

我有两个与切线相关的git存储库。即,一个人的内容是另一个人的前身。我想以某种方式将存储库A的完整历史添加到存放处B中,以便A的提示将成为存储库B的第一个变更集的父级?两者的历史都非常线性。

这可能吗?

1 个答案:

答案 0 :(得分:10)

你可以尝试使用移植文件(.git/info/grafts),你可以覆盖提交的父母身份(就像projectB第一个拥有最新的projectA的父母一样

有关此操作的更多信息,另请参阅“What are .git/info/grafts for?”和“How to prepend the past to a git repository?”。


skalee comments关于文章“Git: Grafting repositories”(来自SO用户 Ben Straub )的具体示例。

  

现在我们要做的是更改“nuevo”repo(“New commit #1”)中的第一次提交,以便其父级是“旧”仓库中的最后一次提交(“旧” #3” )。一些伏都教的时间:

git fetch ../old master:ancient_history
  

Git允许你从任何其他git存储库获取,无论这个repo是否与它相关!辉煌!这让我们留下了这个:

enter image description here

  

注意我们如何将旧的主分支重命名为ancient_history。如果我们没有,git会尝试合并两者,并且可能会厌恶地放弃。

     

现在我们还有问题   两棵树没有连接,实际上git pull甚至根本不会得到ancient_history分支。我们需要一种在两者之间建立联系的方法。

     

Git有一个叫做移植的工具,它基本上伪造了两个提交之间的父链接   要创建一个,只需在此格式的 .git/info/grafts 文件中插入一行:

[ref] [parent]
  

这两个都需要是相关提交的完整哈希值。让我们找到它们:

$ git rev-list master | tail -n 1
d7737bffdad86dc05bbade271a9c16f8f912d3c6

$ git rev-parse ancient_history
463d0401a3f34bd381c456c6166e514564289ab2

$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \
       463d0401a3f34bd381c456c6166e514564289ab2 \
       > .git/info/grafts

(在一行中,suggestedssokolow

echo $(git rev-list master | tail -n 1) $(git rev-parse ancient_history) > .git/info/grafts 

有。现在我们的历史看起来像这样:

enter image description here

  

克隆此repo导致:

enter image description here

  

Woops。事实证明,移植只对本地存储库生效。我们可以通过明智地应用 git fast-import 来解决这个问题:

$ git fast-export --all > ../export

$ mkdir ../nuevo-complete

$ cd ../nuevo-complete

$ git init

$ git fast-import < ../export
git-fast-import statistics: [...]

(在一行中,suggestedssokolow

git filter-branch $(git rev-parse ancient_history)..HEAD 
  

这有效地将我们的“虚假”历史链接转换为真实链接   所有工程师都必须从这个新的存储库中重新克隆,因为哈希值会有所不同,但这是一个很小的代价,无需停机和完整的历史记录。

enter image description here

正如Qix评论below

  

fast-import似乎只是导入git信息,但不会检查任何内容   git init最初让您掌握了主要内容,因此您需要git reset --hard HEAD才能在fast-import 后实际检查文件。