我遇到了一个问题,Git 在尝试 merge 时会说文件有冲突,但当我去解决冲突时,却没有冲突。当本地和远程相同时,为什么 Git 认为这是冲突?有没有办法让 Git 自动解决这个问题?
操作系统:Windows 8
Git 版本:1.9.5
最佳答案
文件肯定不一样。
当 GIT 检测到同一行/ block 在两个 merge 分支中以不同方式更改时,会引发冲突消息。 Git 不会尝试自动解决此类情况,因为解决它们在很大程度上取决于文件内容的语义。 Git 不了解 XML、Java、C# 和 ASN1 语法,也不会尝试学习它们 :) 这是非常非常基础的知识。
但是,对于作为程序员的您来说,有些冲突是“微不足道的”。
这就是为什么您通常使用一些外部 merge 实用程序,如 TortoiseMerge、WinMerge、KDiff3 等。它们包含一些不同的算法/启发式算法,并且恰好能够自动检测/解决经常被解决的常见“琐碎”冲突以同样的方式,甚至被简单地忽略为“不重要”,例如:
- 行结束样式冲突(CR vs CRLF vs LF ..)
- 纯空格冲突(
'class Foobar'
vs'class Foobar'
vs'class Foobar'
) - 编码冲突(ASCII 与 UTF8 与 UTF16)
- 文件结尾冲突(在 EOF 上应该有额外的结尾,而不是没有)
- 等等
其中一些实用程序(尤其是图形实用程序)可能会向您显示文件是“相同的”,因为它们的表观文本内容看起来是相同的,即使原始内容的文件是不同的。这是一个偏好问题。使用纯代码文件时,Java 或 C# 文件是保存为 UTF16 还是 UTF8 通常并不重要 - 您感兴趣的是代码差异。您通常不希望看到每一行都被更改,只是因为您的同事使用 CRLF 而不是 LF 结尾保存它。
但有三个重要注意事项:
- 在这种情况下,一个好的文件 merge 不会通知您“文件是相同的”,而是“文件内容相同,但文件不是二进制相等的”;例如,KDiff3 就是这样做的。
- 空格/行尾/编码/等等可能看起来不重要,但它们不是。以 Makefiles 或 Python 为例。如果有一个空格、三个空格或一个制表符,那会有很大的不同。
- 因此,忽略 whites/encoding/etc 严格取决于文件的用途。在 C# 中编码可能无关紧要,在 FooBar 中它可能很重要。这就是 GIT 不尝试对此类冲突强加任何自动处理的原因。 Git 谨慎行事。您选择的文件差异或文件 merge 为您做到了这一点,并“愚弄”您认为文件是相同的。
关于Git 冲突——显示误报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31050616/