git diff --check 显示不相关分支/文件的更改

标签 git whitespace git-diff git-log

背景

我正在尝试查看当前分支的空白错误(忽略CR 停产)。大多数文件使用CRLF,而我没有core.whitespace 配置集。

这是原始命令:

git -c core.whitespace=trailing-space,cr-at-eol diff --check master..HEAD

HEAD 指的是在旧版本的 ma​​ster 之上创建的分支 (“老大师”)。

问题是 git diff --check 的行为方式出乎意料:它是 不仅显示 ma​​ster..HEAD 中的错误,还显示 老主人..主人

问题

  • 发生这种情况是因为 git diff --check 比较了整个快照 给定的修订范围?

  • 为什么 git loggit 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 Bgit 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 .

请注意,当使用 -pgit 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 showgit diff 命令还会生成带有某些特定参数的组合差异,有时是错误的:特别是-点语法,git diff A...B,旨在比较 AB 的 merge 基础以提交 B,但有时会做不同的事情。另外,当您使用索引并且索引包含冲突的 merge 时,普通的 git diff 将生成组合的差异。

2从技术上讲,它甚至不必提取两个快照 - 它只需直接从它们的树对象中工作即可。它确实必须提取不同的 Blob ,以便计算差异。对于相同的 blob,git diff 知道它们是相同的,因为它们的哈希 ID 匹配。但将其理解为“提取和比较”更容易。

关于git diff --check 显示不相关分支/文件的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51618951/

相关文章:

git - 如何将整个 git repo 输出到单个文件?

git - 如何在 Capistrano 的 deploy.rb 中指明 Git 用户名和密码?

android - 如何将 Android Studio 项目添加到 GitHub

git - 通过 WSL 克隆 GitHub 存储库失败

html - 在 CSS 中使用 "top"标签后删除空白

git diff 不适用于 Word 文档、--intent-to-add 和 pandoc diff 驱动程序

WSL 上的 Git 克隆给出 "permission denied"错误 [WSL1]

html - 当边距设置为 0 时正文上方的空白

java - 带有空格的正则表达式

git diff 与组合 --word-diff