这是一个烦人的。
我用这个命令合并两个分支
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)可以解决此类问题?有没有更好的实际工作方法?
这-X theirs参数仅指导合并对一个文件内的各个冲突的冲突解决,而不是针对高级全文件冲突。
在这种情况下,正如消息所说,冲突在于“他们”( devtemp) 被public/github.css完全删除,而“你”(HEAD ) 对其进行了重命名。您的 Git 不确定在这里要做什么,并已将文件保留在新名称下。
如果您希望执行他们所做的操作,只需将git rm文件命名为新名称即可将其删除。但是......请注意,检测到重命名,因此有可能他们实际上根本没有删除该文件,而是删除了另一个文件,其内容(在删除之前)与您的新文件非常相似创建的。在这种情况下,删除该文件可能是错误的。
在所有情况下,每当进行合并时,明智的做法是在提交之前测试结果。-X当与ours或 一起使用时尤其如此theirs。Git 不知道它在组合什么,仅仅依赖于文本相似性,并且可以进行无意义的合并,特别是在发生冲突的情况下盲目偏向一方,但在这些更改不冲突的情况下使用双方的更改时(这就是-X选项做)。
由于您正在运行git merge --squash,由于某种原因无论如何都会抑制最终结果git commit(a la git merge --no-commit),因此您已经期望必须运行git commit单独运行。只需解决冲突(并像往常一样彻底测试)并提交即可。
编辑(根据评论):如果你想以编程方式执行此操作\xe2\x80\x94尽管我建议不要使用\xe2\x80\x94你可以使用git ls-files --stage(也许与-z可以使用以获得更好的机器可读输出)。任何非零阶段条目都意味着合并失败。索引的内容会告诉你发生了什么:
git rm -- <path> ) 以删除“他们的”。git add -- <path>) 以对其进行重命名。(您将需要设置一个测试用例并验证这是正确的路径。)git checkout --theirs -- <path>将其版本提取到工作树,然后git add -- <path>切换到其版本。我认为这应该涵盖所有未解决的案件。或者,如果您遇到从来没有任何实际重命名的情况,您会从 Git 的重命名检测代码中得到错误的命中,并且您会想要-X no-renames禁用它。