是否有一种干净的方式来处理以相同内容开头的两个原始git存储库?

Ott*_*tto 5 git

假设我有两个从相同的初始内容创建的存储库.例如,如果我使用git来管理/ etc/apache2中的apache配置文件,我会分别git init在machine-a和machine-b上运行.

我已经对machine-b进行了一些配置更改,我希望将其应用于机器上的配置,而不会覆盖诸如主机名之类的非常见内容.

如果我这样做:

machine-a% remote add machine-b ssh://...
machine-a% git fetch machine-b
Run Code Online (Sandbox Code Playgroud)

我得到了机器b上的所有提交,而GitX显示了一组完全断开的提交,正如我所料.

但是,如果我尝试合并任何机器b的更改,我会在所有修改的行上出现冲突.

就我的目的而言,这已经足够了,但我想知道,有更清洁的解决方案吗?

Pie*_*ter 4

你可能想看看 git 移植。一些信息可以在这里找到:http://git-scm.com/docs/git-filter-branch

基本上,你想做的就是伪造祖先。

您在两台机器上进行了初始提交——我们将它们称为“baseA”和“baseB”。然后,您在两侧的基础上创建了第二个提交——“secondA”和“secondB”。你想要做的是告诉 git 'secondB' 没有 'baseB' 作为祖先,而是以 'baseA' 作为父代。

您可以通过使用移植物来实现这一点。例如,将其放入您的 .git/info/grafts 文件中:

secondB baseA
Run Code Online (Sandbox Code Playgroud)

(但随后使用真正的 SHA)。现在,如果您查看 GitX,您会发现历史记录是相互关联的。要使更改永久生效,您需要运行 git filter-branch。

根据评论更新

我不确定你所做的是否“正确”,尽管它会起作用。如果你做了你所做的事情,你将得到历史:

 BaseA --- SecondA -- .. - ..  - Merge
   \ BaseB --- SecondB ... - .. /
Run Code Online (Sandbox Code Playgroud)

这将起作用(并且合并将成功而不会出现问题)。然而,更好一点的是:

 BaseA --- SecondA -- .. - ..  - Merge
   \ SecondB ... - .. /
Run Code Online (Sandbox Code Playgroud)

这基本上会删除“BaseA”作为提交并将“BaseA”设置为 SecondB 的父级。使用我告诉过你的嫁接规则这应该是可能的。

为了演示这一点,我创建了一个小型存储库,您可以在此处下载。

如果您查看 GitX 中的历史记录(“gitx master secondary_master”),您会发现历史记录已断开连接。如果将 .git/info/_grafts 文件移动到 .git/info/grafts,您将获得第二个漂亮的历史记录。

我还添加了一个 .git/info/wrong_grafts 文件。如果您使用它,您将获得您创建的历史记录。

如果您查看移植文件中的 SHA,您会发现 _grafts 文件基本上包含以下内容:

SecondB BaseA
Run Code Online (Sandbox Code Playgroud)

错误的_grafts 文件有这样的内容:

BaseB BaseA
Run Code Online (Sandbox Code Playgroud)