GIT 合并不相关的历史记录

GIT merging unrelated histories

我正在合并两个不相关的历史记录。三向合并不起作用,因为没有 "base" 提交(或文件)可供比较。所以每个文件都是冲突的(因为它想合并整个文件)。无论如何要创建一个 "dummy" 祖先以使这个基础提交用于实际合并(只有不同​​的行被合并或冲突

我有两个回购协议。不幸的是,其中一个只是从另一个复制过来的,开发人员已经为此工作了很长时间。它们非常相似。现在我想合并它们。因为他们没有(从 git 的角度来看)共同的历史。当我合并它们时,没有要合并的基础文件,因此所有文件都会发生冲突,git 想要合并这两个文件(所有行)。我无法更好地解释它。

试试这个命令,可能会有帮助

git pull --allow-unrelated-histories

Is there anyway to create a "dummy" ancestor to have this base commit for the actual merge (only the lines which differ to be merged or conflict ...

不容易。

可以使用git replace --graft在合并期间插入虚拟祖先。但是您必须手动为该虚拟提交提出 content 。除非您必须重复执行此合并,否则您最好 运行 git merge --allow-unrelated-histories 并手动修复结果,因为为每个 add/add 冲突提供基础文件同样重要解决每个 add/add 冲突。

假设您编写了一个程序或脚本,通过采用公共行从两个 add/add 冲突输入中得出一个基本文件。您仍然可以继续这样做。你可以做的是:

git merge --allow-unrelated-histories <commit-specifier>

for file in $(cat list-of-add-add-conflict-files); do
    git show :2:$file > file.ours
    git show :3:$file > file.theirs
    program_or_script file.ours file.theirs > file.base
    git merge-file file.ours file.base file.theirs
    mv file.ours $file; rm file.theirs file.base # this rm can be deferred
done

这使用 git merge-file 命令合并三个单独的文件。本例中的三个文件是:

  • file.ours:来自索引槽 2 的副本,即来自 HEAD
  • file.theirs:来自索引槽 3 的副本,即来自他们的 tip 提交;
  • file.base:您的程序或脚本产生的文件

git merge-file 命令与 Git 默认使用的低级合并驱动程序相同,提取到一个单独的程序中,您可以 运行。所以这会产生相同的结果,如果你在每个文件对上 运行 这个程序并创建一个虚拟祖先,提交它,并使用 git replace --graft 插入它。但是您不必 运行 git commit 进行虚拟提交然后移植它,因此您节省了几个步骤。