“-X theirs”选项似乎不适用于某些 Git 冲突

Ale*_*lls 5 git git-merge

这是一个烦人的。

我用这个命令合并两个分支

git checkout -b temp public/master
git merge -Xtheirs --squash -m "squashed with devtemp" devtemp
Run Code Online (Sandbox Code Playgroud)

我遇到了一些冲突:

CONFLICT (rename/delete): public/github.css deleted in devtemp and renamed in HEAD. Version HEAD of public/github.css left in tree.
Removing public/extra-html/exit-codes.html
Removing public/.gitkeep
Auto-merging package.json
Squash commit -- not updating HEAD
Automatic merge failed; fix conflicts and then commit the result.
Run Code Online (Sandbox Code Playgroud)

怎么能忽略这种类型的冲突?我虽然 --theirs/--ours (或任何适用于这些命令的正确 Git API)可以解决此类问题?有没有更好的实际工作方法?

tor*_*rek 5

-X theirs参数仅指导合并对一个文件内的各个冲突的冲突解决,而不是针对高级全文件冲突。

\n\n

在这种情况下,正如消息所说,冲突在于“他们”( devtemp) 被public/github.css完全删除,而“你”(HEAD ) 对其进行了重命名。您的 Git 不确定在这里要做什么,并已将文件保留在新名称下。

\n\n

如果您希望执行他们所做的操作,只需将git rm文件命名为新名称即可将其删除。但是......请注意,检测到重命名,因此有可能他们实际上根本没有删除该文件,而是删除了另一个文件,其内容(在删除之前)与您的新文件非常相似创建的。在这种情况下,删除该文件可能是错误的。

\n\n

在所有情况下,每当进行合并时,明智的做法是在提交之前测试结果。-X当与ours或 一起使用时尤其如此theirs。Git 不知道它在组合什么,仅仅依赖于文本相似性,并且可以进行无意义的合并,特别是在发生冲突的情况下盲目偏向一方,但在这些更改不冲突的情况下使用双方的更改时(这就是-X选项做)。

\n\n

由于您正在运行git merge --squash,由于某种原因无论如何都会抑制最终结果git commit(a la git merge --no-commit),因此您已经期望必须运行git commit单独运行。只需解决冲突(并像往常一样彻底测试)并提交即可。

\n\n

编辑(根据评论):如果你想以编程方式执行此操作\xe2\x80\x94尽管我建议不要使用\xe2\x80\x94你可以使用git ls-files --stage(也许与-z可以使用以获得更好的机器可读输出)。任何非零阶段条目都意味着合并失败。索引的内容会告诉你发生了什么:

\n\n
    \n
  • 基本版本存在,我们的存在,他们的不存在:重命名/删除冲突,其中 Git 保留了“我们的”重命名版本。删除我们的(git rm -- <path> ) 以删除“他们的”。
  • \n
  • 基本版本存在,他们的存在,我们的不存在:重命名/删除冲突,其中我们删除了文件但他们重命名了它。工作树可能(我没有测试过)在其名称下有该文件。添加它 ( git add -- <path>) 以对其进行重命名。(您将需要设置一个测试用例并验证这是正确的路径。)
  • \n
  • 基本版本不存在,他们的存在,我们的存在:创建/创建冲突。毫无疑问,Git 将我们的文件版本保留在树中。使用git checkout --theirs -- <path>将其版本提取到工作树,然后git add -- <path>切换到其版本。
  • \n
\n\n

我认为这应该涵盖所有未解决的案件。或者,如果您遇到从来没有任何实际重命名的情况,您会从 Git 的重命名检测代码中得到错误的命中,并且您会想要-X no-renames禁用它。

\n

  • 您可以使用 git ls-files --stage 来读取合并后的索引,看看是否存在冲突,并按照您预先选择的分辨率进行编程。然而,自动合并“几乎总是”是一个糟糕的计划。您遇到此问题的事实表明您尚未发现“几乎总是”这一百万分之一的例外情况。我建议不要这么做。 (2认同)