所以让我们先将所有的对象放在一个仓库中,然后再考虑合并。
git fetch theirs
现在你已经有了
A
d
d
处的内容(TREE
)与D
处的内容相同。
现在,您想将H
到J
合并到master
中,并将D
视为合并基础。您可能可以想出一些组合的命令来完成这个任务。但我不会这样做。
相反,我会考虑如何最好地合并历史记录。最简单的方法是将H
到J
变基到D
上。类似的,但处理更少/发生奇怪事情的机会更小,是将H
重新父节点化而不是变基。(因为d
和D
具有相同的内容,所以无论使用哪种操作,结果应该是相同的。)
要更改
H
的父节点,您需要使用带有
--parent-filter
选项的
git filter-branch
命令。您需要查找
d
和
D
的提交 ID(SHA)值,然后可能使用一个
sed
脚本,将
d
ID 替换为
D
ID。有关详细信息,请参见
filter-branch
文档;我很确定有一个恰好符合这种情况的例子。
如果您不想处理这个问题,就像我说的,在这种情况下重新基础操作应该是等效的。您仍然需要一个表达式来解析到
D
,比如在示例中的
master~3
,或者提交 ID 也可以。还需要一个解析到
d
的表达式,例如在示例中用到的
theirs/master~3
。
git checkout theirs/master
git checkout -b temp
git rebase --onto master~3 theirs/master~3
这会给你
A
\
H'
d
现在你可能只想将temp
合并到master
并且丢弃theirs/master
;但是潜在的风险是H'
,I'
和J'
是新的提交(具有新的ID值等),因此如果您要继续维护theirs
存储库并希望迁移更改,这种方法会在下一次迁移时留下相同的问题。
因此,如果您要保留theirs
,可以进行以下调整:
在这种情况下,理想情况下,您希望使用theirs
的原始提交,但这并不是非常容易做到的。相反,您可以在将temp
合并到master
之前,对theirs/master
进行一种“虚假合并”。
git checkout temp
git merge -s ours theirs/master
现在你有了
A
\
H'
/
d
JJ
可能看起来像是一个“邪恶的合并” - 它的内容不是将 J'
和 J
合并的自然/默认结果。但是,考虑到这些历史记录,这样的合并应该会产生冲突 - 也就是说,对于这样的合并,不应该存在“自然/默认结果”。因此,这并不令人困扰。
这意味着 J
、J'
和 JJ
都具有相同的内容,将 temp
合并到 master
应该仍然可以得到正确的结果。
A
\ /
H'
/
d
此时您可以删除temp
。
保留d
、H
、I
、J
和JJ
的目的,正如我所说,是为了方便以后从theirs
进行更新。在未来的获取中,您可能会得到:
A
\ /
H'
/
d
从这个状态开始,你可以简单地将
theirs/master
合并到
master
中,因为Git会计算出
J
是合并基础。
git merge
命令也有--allow-unrelated-histories
选项。 - Qeek