背景
我正在尝试查看当前分支的空白错误(忽略CR 停产)。大多数文件使用CRLF,而我没有core.whitespace 配置集。
这是原始命令:
git -c core.whitespace=trailing-space,cr-at-eol diff --check master..HEAD
HEAD 指的是在旧版本的 master 之上创建的分支 (“老大师”)。
问题是 git diff --check
的行为方式出乎意料:它是
不仅显示 master..HEAD 中的错误,还显示
老主人..主人。
问题
发生这种情况是因为 git diff --check 比较了整个快照 给定的修订范围?
为什么
git log
和git diff
在这种情况下表现不同?git diff --check
不应该只比较已更改的行中已更改的行 文件?
信息
大师 vs 老大师(数字巧合):
$ 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..master 中更改的文件:
$ 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
与 git diff A..B
— 在这里无关紧要。 Git 提取快照 A,提取快照 B,然后比较这两个快照。您使用的任何标志选项(例如 --check
)都会应用于此特定比较。提交 A
不必是 B
的祖先,反之亦然; Git 不会查看这两个提交“之间”的任何提交;它只是提取 A
,然后提取 B
,并比较它们。2
git log
命令做了一些非常不同的事情:它遍历修订图。给定 git log A..B
,Git 查找所有可从 B
访问但无法 访问的提交>A
。有关可达性的明确定义,请参阅Think Like (a) Git .
请注意,当使用 -p
和 git log
将提交视为补丁时,git log
会将每个提交与其(单个)父提交进行比较。例如,如果 A..B
范围内有 3 个提交,git log -p A..B
首先显示 B
并运行git diff B^ B
,然后显示 B^
并运行 git diff B^^ B^
,最后显示 B^^
并运行git diff B^^^ B^^
。 (这假设范围内没有 merge 提交,但 git log 无论如何都会默认忽略 merge 提交的补丁。)
1要查看组合差异,请在 merge 提交上使用 git show
。 git diff
命令还会生成带有某些特定参数的组合差异,有时是错误的:特别是三-点语法,git diff A...B
,旨在比较 A
和 B
的 merge 基础以提交 B
,但有时会做不同的事情。另外,当您使用索引并且索引包含冲突的 merge 时,普通的 git diff 将生成组合的差异。
2从技术上讲,它甚至不必提取两个快照 - 它只需直接从它们的树对象中工作即可。它确实必须提取不同的 Blob ,以便计算差异。对于相同的 blob,git diff
知道它们是相同的,因为它们的哈希 ID 匹配。但将其理解为“提取和比较”更容易。
关于git diff --check 显示不相关分支/文件的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51618951/