>Background
我正在尝试查看当前分支的空格错误(在 eol 处忽略CR)。 大多数文件都使用CRLF,我没有设置core.whitespace配置。
这是原始命令:
git -c core.whitespace=trailing-space,cr-at-eol diff --check master..HEAD
HEAD是指在旧版本的master(">oldmaster")之上创建的分支。
问题是git diff --check
的行为方式出乎意料:它是 不仅显示主中的错误..HEAD,还有错误老大师..师傅。
问题
发生这种情况是因为
git diff --check
比较了整个快照 给定的修订范围?为什么在这种情况下
git log
和git diff
的行为不同?git diff --check
不应该只比较更改后的行吗 文件?
信息
大师与老大师(数字是巧合):
$ git log --oneline oldmaster..master | wc -l
115
$ git diff --name-only oldmaster..master | wc -l
115
这将正确显示相关提交:
$ git log --oneline master..HEAD | wc -l
4
这将显示正确的文件:
$ git log --oneline --name-only master..HEAD -- | grep -E '^[a-zA-Z]+/'
| sort -u | wc -l
4
由于某种原因,这些还包括在 oldmaster 中更改的文件。师傅:
$ git diff --name-only master..HEAD -- | wc -l
119
$ git -c core.whitespace=trailing-space,cr-at-eol diff --name-only
master..HEAD -- | wc -l
119
这两个也显示不相关的文件:
$ git diff --check master..HEAD -- | grep -E '^[a-zA-Z]+/' | cut -d : -f 1
| sort -u | wc -l
30
$ git -c core.whitespace=trailing-space,cr-at-eol diff --check master..HEAD
-- | grep -E '^[a-zA-Z]+/' | cut -d : -f 1 | sort -u | wc -l
9
除了组合差异(您在此处不使用)之外,git diff
严格比较两个快照。1使用的语法——git diff A B
vsgit diff A..B
——在这里无关紧要。 Git 提取快照 A,提取快照 B,并比较这两个快照。 您使用的任何标志选项(如--check
)都将应用于此特定比较。 承诺A
不必是B
的祖先,反之亦然;Git 不会查看这两个提交"之间的"任何提交;它只是提取A
,然后提取B
,并区分它们。阿拉伯数字
git log
命令执行一些非常不同的操作:它遍历修订图。 给定git log A..B
,Git 会找到所有可从B
访问的提交,而从A
无法访问。 有关可访问性的明确定义,请参阅像 (a) Git 一样思考。
请注意,当将-p
与git log
一起使用以补丁形式查看提交时,git log
将每个提交与其(单个)父级进行比较。 例如,如果A..B
范围内有三个提交,git log -p A..B
首先显示B
并运行git diff B^ B
,然后显示B^
并运行git diff B^^ B^
,最后显示B^^
并运行git diff B^^^ B^^
。 (这假设该范围内没有合并提交,但默认情况下git log
省略合并提交的补丁。
1要查看组合的差异,请在合并提交中使用git show
。git diff
命令也会产生与一些特定参数的组合差异,有时是错误的:特别是三点语法,git diff A...B
,旨在比较A
和B
的合并基础以提交B
,但有时会做一些不同的事情。 此外,当您使用索引并且索引包含冲突的合并时,普通git diff
将产生组合差异。
2从技术上讲,它甚至不必提取两个快照 - 它只是直接从它们的树对象工作。 它确实必须提取不同的斑点,以便计算差异。 对于相同的 blob,git diff
知道它们是相同的,因为它们的哈希 ID 匹配。 但更容易将其推理为"提取和比较"。