如何连接两个git历史?

Sil*_*ost 12 git history repository

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

这可能吗?

Von*_*onC 11

您可以尝试使用移植文件(.git/info/grafts),在那里您可以覆盖提交的父母身份(比如第一次projectB为父母提供最新的projectA)

另请参阅" 什么是.git/info/grafts for? "和" 如何将过去添加到git存储库? "以获取有关此操作的更多信息.


skalee 评论有关的文章" :接枝库GIT中(从SO用户" 奔斯特劳布对于一个具体的例子).

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

git fetch ../old master:ancient_history
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

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

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

[ref] [parent]
Run Code Online (Sandbox Code Playgroud)

这两个都需要是有问题的提交的完整哈希.所以让我们找到它们:

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

$ git rev-parse ancient_history
463d0401a3f34bd381c456c6166e514564289ab2

$ echo d7737bffdad86dc05bbade271a9c16f8f912d3c6 \
       463d0401a3f34bd381c456c6166e514564289ab2 \
       > .git/info/grafts
Run Code Online (Sandbox Code Playgroud)

(在一行中,如ssokolow建议那样)

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

那里.现在我们的历史看起来像这样:

在此输入图像描述

克隆此repo导致:

在此输入图像描述

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: [...]
Run Code Online (Sandbox Code Playgroud)

(在一行中,如ssokolow建议那样)

git filter-branch $(git rev-parse ancient_history)..HEAD 
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

正如Qix评论如下:

fast-import似乎只是导入git信息,但不检查任何内容.
git init最初让你成为主人,所以你需要一个git reset --hard HEAD实际检查后你的文件fast-import.