我想继续讨论我的另一个问题:Merge two Git repositories and keep the master history
我成功地将2个不同的回购合并为一个回购。我需要一个rebase才能成功地做到这一点。主人是正确的,但我还想保留合并历史记录。这可能吗?
我有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:在我的案件中表现最佳'贪污'确实为我揭示了正确的工作答案。
回答2 “LeGEC”中的“替换”选项也为某些用例提供了良好的结果。一个异常留给我:
答案3:值得添加来自'VonC'的回答。在我的情况下,我无法获得“--preserve-merges working”选项。这可能适用于其他场景,但我没有测试这种情况。
答案 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}}。