如何合并两个 git 存储库,同时保留两者的历史记录和其中一个的哈希值?

How to combine two git repos, preserving the history of both, and the hashes of one?

我有什么

我有 read questions about combining repositories。我快到了,但我错过了一些东西。

我有两个存储库 current-repo,一个是发布和共享的,另一个是 old-repo。我有唯一的副本。他们的历史看起来像

                         1--2--3--4--5  <= current-repo
                         =
                content is the same
                         =
old-repo =>  a--b--c--d--e

我想要的

理想情况下,通过合并这两个回购协议,我会得到一个具有类似

历史记录的回购协议
1. a--b--c--d--1--2--3--4--5  <= notice, duplicate old entry "e" is dropped"

我还会满足于以下条件:

2. a--b--c--d--e--1--2--3--4--5            <= duplicate content in "e" and "1"
3. foo--bar--baz--buz--1--2--3--4--5       <= like #1 above, but rehashed "old" history
4. foo--bar--baz--buz--bif--1--2--3--4--5  <= like #4, but "bif" and "1" have duplicate content

我试过的

我可以(在本地)使用

cd ~/current-repo
git remote add -f old-repo ~/old-repo
git replace -f --graft 1 d

现在,据我了解,此时我必须 push/pull refs/replace/*。我不希望我的用户必须执行此步骤。

我看到的git graft(可能还有一些git replace)解决方案有一个git filter-branch步骤。我试过这个,也试过 git rebase-ing,但只重写了 current-repo 历史中的哈希值。我也不想这样我不在乎 old-repo 的历史是否被重新散列。正如我提到的,该回购协议未发布和共享。基本上,下次我的用户执行 git fetch 时,除了他们丢失的任何 "new" 历史之外,他们还会得到一堆旧历史。

tl;博士

我想合并两个 git 存储库,维护线性历史,并维护 "newer" 存储库的哈希值。如何访问包含我选择的历史记录(以上)或类似内容的存储库?

tl;dr

不行,做不到。

详情

在开始时添加更多历史记录的同时保留散列是不可能的,这是设计使然。

提交的 sha1 散列基于加密签名的概念:它不仅对提交及其内容、日期、提交者等进行散列,而且还对其中的父项进行散列,这意味着它散列导致该提交的整个历史记录。

因此,如果不更改历史被扩展(或以任何其他方式修改)的每个提交的哈希值,就无法更改历史。