Git 冲突 -- 显示误报

Git Conflict -- Showing False Positive

我 运行 遇到一个问题,在尝试合并时 Git 会说文件存在冲突,但当我去解决冲突时,却没有冲突。为什么 Git 认为本地和远程都相同时会发生冲突?有没有办法让 Git 自动解决这个问题?

OS: Windows 8

Git版本:1.9.5

文件肯定不一样。

当 GIT 检测到相同的 line/block 在两个合并的分支中以不同的方式更改时,会引发冲突消息。 Git 不会尝试自动解决此类情况,因为解决它们在很大程度上取决于文件内容的语义。 Git 不知道 XML 也不知道 Java 也不知道 C# 和 ASN1 语法并且不尝试学习它们 :) 这是非常非常基础的知识。

但是,对于作为程序员的您来说,有些冲突 "trivial"。

这就是为什么您通常使用一些外部合并实用程序,如 TortoiseMerge、WinMerge、KDiff3 等。它们包含一些不同的 algorithms/heuristics,而那些碰巧能够自动 detect/solve 通用 "trivial" 经常以相同方式解决的冲突,或者甚至被简单地忽略为 "unimportant" 的冲突,例如:

  • 行结束样式冲突(CR vs CRLF vs LF ..)
  • whitespace-仅冲突('class Foobar' vs 'class Foobar' vs ' class Foobar'
  • 编码冲突(ASCII vs UTF8 vs UTF16)
  • 文件结尾冲突(应该在 EOF 上有额外的结尾而不是没有)
  • 等等

其中一些实用程序(尤其是图形实用程序)可能会向您显示文件是 "identical",因为它们的 表观文本内容 看起来是相同的,即使 文件的原始内容不同。这是一个偏好问题。使用纯代码文件时,Java 或 C# 文件是保存为 UTF16 还是 UTF8 通常并不重要 - 您感兴趣的是 代码差异 。您通常不希望看到每一行都被更改只是因为您的同事用 CRLF 而不是 LF 结尾保存它。

三个重要注意事项:

  1. 在这种情况下,一个好的文件合并不会通知您 "files are identical",而是 "file contents are identical, but files are not binary equal";例如,KDiff3 就是这样做的。
  2. whitespaces/lineendings/encodings/etc看似不重要,实则不然。以 Makefile 或 Python 为例。如果有一个 space 或三个或一个制表符,则差别很大。
  3. 因此,忽略whites/encoding/etc 严格取决于文件的用法。在 C# 中编码可能无关紧要,在 FooBar 中它可能很重要。这就是为什么 GIT 不尝试对此类冲突强加任何自动处理。 Git 谨慎行事。您选择的文件差异或文件合并为您和 "fooled" 您认为文件是相同的。