为什么使用 ^! 合并提交的差异会反转?父符号

Why is the diff reversed for a merge commit with ^! parent notation

为什么 ^! 反转合并提交的差异?

来自Other ^ Parent Shorthand Notations

The r1^! notation includes commit r1 but excludes all of its parents. By itself, this notation denotes the single commit r1.

这正确地显示了非合并提交的差异。

$ git diff <commit>^!

但是对于合并提交,差异是相反的。

$ git diff <merge-commit>^!

difftool 我得到了类似的结果。

为什么会这样?

简短的回答是这是一个错误。

您可以使用 git rev-parse 查看 git diff 有效查看的内容。这是应用于普通提交的 ^! 后缀:

$ git rev-parse 699d47e1d^!
699d47e1d2777ad1c2a867671e35daa821769f29
^4aaf5b0b21ac1fc294066593ac5243b3eaff897b

此处它应用于合并提交:

$ git rev-parse 117ddefdb^!
117ddefdb4dfd9b40ae60967a7327754d8ce7a87
^5e5a7cd9327cdbe6b50b5a0ead9b2ee5fb30789c
^699d47e1d2777ad1c2a867671e35daa821769f29

当您向 git diff 提供压缩符号时,Git 通过 git rev-parse 使用的相同扩展代码传递它。但是,git diff 并没有打印出来,而是尝试反向解释结果。如果有两个提交哈希(带有不同的标志),它会在两个命名的提交之间运行差异。如果有三个或更多,它会做一些不同的事情。

相关(但不完全相同):