Git使用符号链接重新设置和合并问题

时间:2019-02-05 05:03:18

标签: git git-merge symlink git-rebase merge-conflict-resolution

git rebasegit merge期间,符号链接似乎被转换为纯文件。

在分支上运行git rebase master时遇到符号链接的以下问题。

首先,了解一些背景:

  • master不包含所讨论的符号链接,但包含符号链接的所有目标。
  • 有问题的符号链接一次提交都添加到了分支中。

在重新设置基准期间,每个符号链接都有一个“ CONFLICT (add/add): Merge conflict in ...”。当我在每个假定的符号链接上执行git ls-files --stage时,它显示的模式为100644(即普通文件,而不是符号链接)。我编写了一个简单的Shell脚本,用所需的符号链接替换了每个文本文件,将它们添加到索引中,然后继续进行重新设置。

前一段时间,我注意到我在先前的上一个分支上添加的一组符号链接已转变为master上的纯文本文件,每个文件都只包含以前作为链接目标的路径;当时我怀疑更改是在从分支合并到master的合并过程中发生的,现在我更加确定。

所以我的问题是:

  1. 有没有办法让Git在合并期间更好地处理符号链接?
  2. 如果git rebasegit merge引发冲突并将符号链接更改为纯文件,是否有比删除每个文件并重新创建符号链接更好的方法来解决此问题?

1 个答案:

答案 0 :(得分:2)

  

有没有办法让Git在合并过程中更好地处理符号链接?

不是,不是。如果添加的两个文件具有 same 内容,则Git根本不认为这是冲突(我刚刚对此进行了测试),并且合并成功。

最终,问题在于符号链接,而数据是链接的目标,而链接仅是一行(没有终止换行!)。但是,具有足够链接能力的OS专门存储此数据,并且只能专门访问它。 (Windows通常不是 not 足以链接-y,而是将其存储为纯文本文件。)因此,假设两个要提交的两个待合并文件中的两个符号链接与原始文件不同原始提交中的符号链接:

merge base: file foo should be a symlink to bar/baz
--ours:     file foo should be a symlink to our/name
--theirs:   file foo should be a symlink to different/path

由于全部都是一行,因此Git无法合并这两个更改,这两个更改都更改了合并基础文件的同一源行(第1行是 only 行)。您必须手动合并它们。

(在您的情况下,根本没有第1阶段的条目,只有第2和第3阶段,因此出现了“添加/添加冲突”,这就是我所说的永不消失的高级冲突进入低级文件合并代码。下面的描述更多地用于低级冲突情况,这种情况也可能发生,并且是-X ours-X theirs可以工作的地方。 Git永远不会进入-X处理代码。)

  

当我在每个假定的符号链接上执行git ls-files --stage时,它显示的模式为100644(即纯文件,而不是符号链接)。

这可以说是一个错误。我会注意到,当我尝试将其作为实验时,那不是我得到的:

$ git ls-files --stage
100644 79f977c119cd6951428b04565177cb4e53dd4bc3 0       README
100644 fa49b077972391ad58037050f2a75f74e3671e92 0       newfile
120000 1b407f24bddc88f87d93302f462251bf881acbc9 2       newlink
120000 1de565933b05f74c75ff9a6520af5f9f8a5a2f1d 3       newlink

请注意此处的mode 120000行。该符号链接也仍然是我的工作树中的符号链接:

$ ls -l newlink
lrwxr-xr-x  1 torek  torek   9 Feb  5 00:55 newlink -> newtarget

合并基础中存在第三个(不同的)符号链接,我不确定Git会将我的工作树文件保留为符号链接。

(我希望git mergetool最终将这两个解压缩到纯文件中:

$ git checkout-index --temp --stage 2 newlink
.merge_link_OzyiFR      newlink

因此,如果您使用的是git mergetool,实际上是git mergetool的错。但这不能将索引输入模式设置为100644。)

  

如果git rebasegit merge引发冲突并将符号链接更改为纯文件,是否有比删除每个文件并重新创建符号链接更好的方法来解决此问题?

不是,不是。您必须选择哪个链接(我们的vs他们的链接),以便选择一个或什至是第三个值(也许返回到合并基本版本或其他路径)。

请注意,如果只有一个“一侧”(我们或他们的一侧)更改了链接的目标,您将不会发生合并冲突。在这种情况下,merge-base与我们的相同,因此Git进行更改,或者merge-base与他们的相同,因此Git进行更改-就像对任何常规文件所做的一样。 (请参见the three-way merge section of the git read-tree documentation。)

从逻辑上讲,-X ours-X theirs应该自动解决冲突,但仅在真正的三向合并的情况下。如果存在添加/添加冲突(因为两个符号链接的目标,两次技巧提交中的目标不同,并且基础中根本没有符号链接),我们将永远无法解决这一点,-X也无济于事。

相关问题