合并两个Git repos并保留历史记录

时间:2017-02-17 07:45:39

标签: git merge repository rebase

我想继续讨论我的另一个问题:Merge two Git repositories and keep the master history

我成功地将2个不同的回购合并为一个回购。我需要一个rebase才能成功地做到这一点。主人是正确的,但我还想保留合并历史记录。这可能吗?

我有2个存储库:

Repo A

Repo B

这是变基后的结果。 顶级回购的时间是转折时间。原始日期丢失了!

Rebase

我就这样做了:

# 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

有可能有这样的东西吗?画解决方案!!!

Painted

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

更新 - 答案

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

答案1:在我的案件中表现最佳'贪污'确实为我揭示了正确的工作答案。

GitHub: RepoGraft

enter image description here

回答2 “LeGEC”中的“替换”选项也为某些用例提供了良好的结果。一个异常留给我:

GitHub: RepoHistory

enter image description here

答案3:值得添加来自'VonC'的回答。在我的情况下,我无法获得“--preserve-merges working”选项。这可能适用于其他场景,但我没有测试这种情况。

3 个答案:

答案 0 :(得分:6)

正如您所发现的,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

的初始提交

从技术上讲,如果您在replace中实际上没有任何有价值的内容,则可以跳过第一个master,只会产生RepoB + RepoA的历史记录。

这些命令在refs/replace/*中创建条目,可以推送和拉动条目以与其他人共享您修订的历史记录。或者,如果您不关心保留RepoA / RepoB的SHA,则可以通过运行git filter-branch --all来生成替换永久,以生成所需谱系的“真实”提交集

答案 1 :(得分:1)

在你的情况下,git rebase中有两个选项值得关注:

p
--preserve-merges
  

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

--committer-date-is-author-date 

(来自git am

  

默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并使用提交创建时间作为提交者日期。这允许用户使用与作者日期相同的值来说谎提交者日期。

测试第二个rebase是否不会产生更好的结果:

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

答案 2 :(得分:1)

此答案提示了使用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),然后您可以使用git replace abcdef history/master来提交存储在{{{ 1}}。