合并两个Git repos,保留/移植完整历史记录(不重写)

b4wnujal  于 2023-02-02  发布在  Git
关注(0)|答案(3)|浏览(127)

我想补充一下我的另一个问题:Merge two Git repositories and keep the master history
我已经成功地将两个不同的存储库合并为一个存储库。我需要一个重定基来成功完成此操作。主存储库是正确的,但是我还想保留合并历史记录。这可能吗?
我有2个存储库:

这是重定基后的结果。顶部回购的时间是重定基时间。原始日期丢失!

我是这样做的:

# Assume the current directory is where we want the new repository to be created
# Create the new repository
git init

# Before we do a merge, we have to have an initial commit, so we'll make a dummy commit
dir > Read.md
git add .
git commit -m "initial commit"

# Add a remote for and fetch the old RepoA
git remote add -f RepoA https://github.com/DimitriDewaele/RepoA

# Do the same thing for RepoB
git remote add -f RepoB https://github.com/DimitriDewaele/RepoB

# Rebase the working branch (master) on top of repoB
git rebase RepoB/master

# Rebase the working branch (master with RepoB) on top op repoA
git rebase RepoA/master

有可能有这样的东西吗?(* 油漆解决方案!!!*)

我想保留原始时间+合并历史记录。

更新-答复

最适合我的答案是使用嫁接点,但其他答案在其他用例中也非常有用,我已经在github上添加了我的结果,所以每个人都可以评估。

答案1:最适合我的情况“嫁接”确实为我揭示了正确的工作答案。

GitHub: RepoGraft

答案2“LeGEC”中的“replace”选项在某些用例中也能给出很好的结果。

GitHub: RepoHistory

答案3:值得添加来自“VonC”的答案。在我的情况下,我无法获得选项“--preserve-merges working”。这在其他情况下可能有效,但我没有进一步测试。

rdlzhqv9

rdlzhqv91#

正如你所发现的,rebase并不是你想要用来拼接历史的命令(因为它实际上重写了历史)。早期的Git有一个特性(hack)专门为你所要做的事情而设计:graft points。更好的是,从1.6.5开始,您可以使用git replace --graft

git checkout master
git replace --graft $(git log RepoB/master --format=%H | tail -1) HEAD
git replace --graft $(git log RepoA/master --format=%H | tail -1) RepoB/master
git reset --hard RepoA/master

git log RepoA/master --format=%H | tail -1返回来自RepoA的初始提交)
从技术上讲,如果您在master中实际上还没有任何有价值的东西,您可以跳过第一个replace,只生成RepoB + RepoA的历史。
这些命令会在refs/replace/*中创建条目,这些条目可以被推送和拉取,以便与其他人共享您修改过的历史记录。或者,如果您不在乎保留RepoA/RepoB的SHA,您可以通过运行git filter-branch --all来生成所需谱系的“真实的”提交集,从而使替换成为“永久”的。

uubf1zoe

uubf1zoe2#

在git rebase中有两个选项,你应该会感兴趣:

p
--preserve-merges

重新创建合并提交,而不是通过重播合并提交引入的提交来展平历史记录。

--committer-date-is-author-date

(from x1月1x)
默认情况下,该命令将电子邮件中的日期记录为提交者日期,并将提交创建的时间作为提交者日期,这允许用户通过使用与提交者日期相同的值来谎报提交者日期。
使用以下方法测试第二次变基是否未产生更好的结果:

git rebase -p --committer-date-is-author-date RepoA/master
6tr1vspr

6tr1vspr3#

这个答案建议使用RepoB作为活动存储库的另一种方法,并且仍然可以访问RepoA历史记录:
使用git replace

# start with a regular clone of the active repo :
$ git clone RepoB

# add repoA as a remote :
$ git remote add -f history https://github.com/DimitriDewaele/RepoA

# get hash of *initial* commit on repoB :
$ git log --oneline origin/master | tail -1
abcdef Initial commit

# get hash of last commit on repoA :
$ git log --oneline history/master | head -1
12345 Merge branch 'develop'

# use 'git replace' to tell git to stitch histories in the log :
$ git replace abcdef 12345

注意:此操作是在您的计算机上完成的,而不是在远程资料库上,因此应该在所有新克隆上重复此操作。

  • 变式 *:

您可以使用新名称将RepoA:master推送到RepoB(例如:RepoB:history/master),那么你就可以在所有存储在RepoB中的提交上使用git replace abcdef history/master

相关问题