由于我已经创建了这些图片,所以我认为在另一个答案中使用它们可能是值得的,尽管 ..
(点-点)和 ...
(点-点-点)之间的区别描述与 manojlds 的答案 本质上是相同的。
git diff
命令通常¹ 只会显示在提交图中恰好两个点之间状态的树之间的差异。 在 git diff
中,..
和 ...
表示如下:
git diff foo..bar
git diff foo bar
git diff foo...bar
git diff $(git merge-base foo bar) bar
![git diff 的不同提交规范示例的插图](https://istack.dev59.com/uWWDV.webp)
换句话说,git diff foo..bar
和 git diff foo bar
是完全相同的;两者都将展示你两个分支 foo
和 bar
之间的差异。而 git diff foo...bar
则会展示你在这两个分支上的“合并基底”和 bar
的最新提交之间的差异。“合并基底”通常是这两个分支之间最后一个公共提交,所以这个命令将展示你在 bar
上的变更,同时忽略 foo
分支中间的所有工作。
这就是关于 git diff
中 ..
和 ...
表示方法的全部内容。然而...
... 这里的一个普遍困惑是,在像 git log
这样需要一组提交作为一个或多个参数的命令中使用 ..
和 ...
表示法时,其意义略有不同。(所有这些命令最终都会使用 git rev-list
从它们的参数中解析一组提交。)
..
和 ...
在 git log
中的含义可以如下图所示:
![git log 的提交范围不同表示方法的插图](https://istack.dev59.com/Fyff5.webp)
因此,git rev-list foo..bar
展示你在分支 bar
上所有不在分支 foo
上的内容。而 git rev-list foo...bar
则展示你在 foo
或 bar
上的所有提交,但不包括两者都有的提交。第三个图表只是表明,如果你列出这两个分支,那么你将会得到它们两者中有的或所有的提交。
总的来说,我觉得这有点混乱,我认为这些提交图表很有帮助 :)
¹ 我只说“通常”是因为例如在解决合并冲突时,git diff
将展示一个三方合并。
git diff
图表的想法,稍后会制作。 - user456814git diff
中,..
和...
的效果与git rev-list
相比似乎是相反的! - Robert Siemer^
出现在引用提交的东西之前时,它表示“不是”。因此,git rev-list bar ^foo
的意思是“除了foo
中的任何内容之外,所有在bar
中的内容都包括在内”。 - Mark Longair