一些 Git 命令采用提交范围,一种有效的语法是用两个点分隔两个提交名称..
,另一种语法使用三个点...
。
两者有什么区别?
一些 Git 命令采用提交范围,一种有效的语法是用两个点分隔两个提交名称..
,另一种语法使用三个点...
。
两者有什么区别?
当您使用..
和...
with之类的提交范围时git log
,它们之间的区别在于,对于分支 A 和 B,
git log A..B
将向您显示B 拥有而 A 没有的所有提交,而
git log A...B
将向您显示A拥有和 B 没有的提交,以及 B 拥有而 A 没有的提交,或者换句话说,它将过滤掉 A 和 B 共享的所有提交,因此只显示他们不共享的提交。
这是 的视觉表示git log A..B
。分支 B 包含但 A 中不存在的提交是提交范围返回的内容,在维恩图中以红色突出显示,在提交树中以蓝色圈出:
这些是 的图表git log A...B
。请注意,命令不会返回两个分支共享的提交:
...
更有用您可以通过使用显示哪些提交属于哪个分支的选项来使三点提交范围...
在日志命令中更有用:--left-right
$ git log --oneline --decorate --left-right --graph master...origin/master
< 1794bee (HEAD, master) Derp some more
> 6e6ce69 (origin/master, origin/HEAD) Add hello.txt
在上面的输出中,您将看到属于的提交master
带有前缀<
,而属于的提交origin/master
带有前缀>
。
有一天我可能会添加我自己的解释来解释提交范围如何与git diff
.范围?.
这取决于您使用的是log
命令还是diff
命令。在这种log
情况下,它在man git-rev-parse
文档中:
要从提交中排除可访问的提交,使用前缀 ^ 表示法。例如 ^r1 r2 表示可从 r2 访问的提交,但排除可从 r1 访问的提交。
这个集合操作经常出现,以至于有一个简写形式。当您有两个提交 r1 和 r2(根据上面指定修订中解释的语法命名)时,您可以请求可从 r2 访问的提交,不包括可通过“^r1 r2”从 r1 访问的提交,它可以写成“r1..r2”。
类似的符号“r1...r2”称为 r1 和 r2 的对称差异,并定义为“r1 r2 --not $(git merge-base --all r1 r2)”。它是可以从 r1 或 r2 之一但不能从两者中访问的一组提交。
这基本上意味着您将获得两个分支中的任何一个中的所有提交,但不是两个分支中的所有提交。
在这种diff
情况下,它在man git-diff
文档中:
git diff [--options] <commit>...<commit> [--] [<path>...] This form is to view the changes on the branch containing and up to the second <commit>, starting at a common ancestor of both <commit>. "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B". You can omit any one of <commit>, which has the same effect as using HEAD instead.
这有点模糊。基本上,这意味着它仅显示该分支与另一个分支相比的差异:它使用您给它的第一个提交查找最后一个常见提交,然后将第二个提交与该提交进行比较。与此分支相比,这是查看该分支中进行了哪些更改的简单方法,而无需仅注意此分支中的更改。
..
稍微简单一些:在这种情况git-diff
下,它与 a 相同git diff A B
,只是将 A 与 B 进行比较。在这种log
情况下,它显示了 B 中但不在 A 中的所有提交。
我认为关于两个点与三个点混淆的最大来源是,当与git diff
它一起使用时,它与与使用时相反git log
。
请参阅其他答案、实际文档或大量博客文章以了解确切的详细信息,但我发现这些简单的陈述可以很好地传达正确的想法:
git log A..B # Show me commits only on B.
git log A...B # Show me commits only on A or only on B.
git diff A..B # Show me changes only on A or only on B.
git diff A...B # Show me changes only on B.
这有点令人困惑=所以这是这个流程的实际情况
A---B---C topic
/
D---E---F---G master
https://github.com/alexcpn/gitdiffs/pull/2/commits https://github.com/alexcpn/gitdiffs/pull/1/commits
Git 日志行为
1 | > git log --oneline --graph topic...main * 9411a8b (HEAD -> main) G * 3a567aa F * aad429f (topic) C * 6b1eb5a B * d65c129 A |
主题 D E A B C |
主 D E F G |
在主题和主要方面,但不在 两者中 |
2 | git log --oneline --graph main...topic * 9411a8b (HEAD -> main) G * 3a567aa F * aad429f (topic) C * 6b1eb5a B * d65c129 A |
主题 D E A B C |
主 D E F G |
和上面一样 |
3 | git log --oneline --graph topic..main * 9411a8b (HEAD -> main) G * 3a567aa F |
主题 D E A B C |
主 D E F G |
主要,但不是主题 |
4 | git log --oneline --graph main..topic * aad429f (topic) C * 6b1eb5a B * d65c129 A |
主题 D E A B C |
主 D E F G |
在主题中,但不在主要内容中 |
Git 差异行为
1 | git diff topic..main D E -A -B -C +F +G |
主题 D E A B C |
主 D E F G |
与主题 相比,主要内容主要内容 |
2 | git diff main..topic D E -F -G +A +B +C |
主题 D E A B C |
主 D E F G |
主题中的内容 与主要 内容相比,主题中没有的内容 |
3 | git diff main...topic D E (你可以在这里换行) +A +B +C |
主题 D E A B C |
主 D E F G |
在主题中,但不在主要内容中 |
4 | git diff 主题...主要 D E +F +G |
主题 D E A B C |
主 D E F G |
主要,但不是主题 |