Git提交范围中的双点“..”和三点“...”有什么区别?

omvjsjqw  于 2023-02-28  发布在  Git
关注(0)|答案(5)|浏览(191)

一些Git命令使用提交范围,一种有效的语法是用两个点..分隔两个提交名,另一种语法使用三个点...
两者有何不同?

kknvjkwl

kknvjkwl1#

'...'语法是“从公共祖先开始的两个分支之间的差异”的简写。从official Git book

git diff master...contrib

相当于:

$ git merge-base contrib master
36c7dba2c95e6bbb78dfa822519ecfec6e1ca649
$ git diff 36c7db
2sbarzqh

2sbarzqh2#

在Git日志中使用提交范围

当你使用..git log这样的提交范围时,它们之间的区别在于,对于分支A和B,

git log A..B

将向您显示B拥有而A没有的所有提交,而

git log A...B

将向您显示***both***A拥有和B没有的提交,以及B拥有但A没有的提交,或者换句话说,它将过滤掉A和B共享的所有提交,从而只显示它们 * 不 * 共享的提交

使用维恩图和提交树进行可视化

下面是git log A..B的一个可视化表示,分支B包含的提交在分支A中不存在,这就是提交范围返回的提交,在维恩图中用红色高亮显示,在提交树中用蓝色圈出:

下面是git log A...B的图表,注意,被两个分支***共享***的提交不会被命令返回:

使三点提交范围...更有用

你可以在log命令中使用--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一起使用

有一天我可能会添加我自己的解释,说明提交范围如何与git diff一起工作,但现在,您可能需要查看What are the differences between double-dot ".." and triple-dot "..." in Git diff commit ranges?

另见

  • Pro Git § 6.1 Git工具-修订选择-提交范围
8ljdwjyq

8ljdwjyq3#

这取决于您使用的是log命令还是diff命令。在log的情况下,它位于man git-rev-parse文档中:
为了排除从一个提交可到达的提交,可以使用前缀^表示法。例如^r1 r2表示从r2可到达的提交,但排除从r1可到达的提交。
这个集合操作经常出现,所以有一个简写。当你有两个提交r1和r2(根据上面的指定修订版中解释的语法命名),你可以请求从r2可达的提交,排除那些从r1通过“^r1r2”可达的提交,它可以写成“r1..r2”。
类似的符号“r1...r2”被称为r1和r2的对称差,定义为“r1 r2 --not $(git merge-base --allr 1 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.

这有点模糊。基本上这意味着它只显示了该分支与另一个分支的差异:它会寻找最后一个与你给它的第一个committish相同的commit,然后将第二个committish与之进行比较。这是一个很容易的方法,可以看到那个分支与这个分支相比有什么变化,而不必只注意这个分支的变化。
..稍微简单一些:在git-diff的情况下,它与git diff A B相同,只是将A与B进行了比较。在log的情况下,它显示了所有在B中但不在A中的提交。

kd3sttzy

kd3sttzy4#

我认为两个点和三个点最大的混淆来源是因为当与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.
kx1ctssn

kx1ctssn5#

This is a bit confusing = So here is a how it is actually for this flow

A---B---C topic
     /
D---E---F---G master

https://github.com/alexcpn/gitdiffs/pull/2/commitshttps://github.com/alexcpn/gitdiffs/pull/1/commits

Git Log Behaviour

1> git log --oneline --graph topic...main* 9411a8b (HEAD -> main) G* 3a567aa F* aad429f (topic) C* 6b1eb5a B* d65c129 AtopicDEABCmainDEFGIn topic and main, but not in both
2git log --oneline --graph main...topic* 9411a8b (HEAD -> main) G* 3a567aa F* aad429f (topic) C* 6b1eb5a B* d65c129 AtopicDEABCmainDEFGSame as above
3git log --oneline --graph topic..main* 9411a8b (HEAD -> main) G* 3a567aa FtopicDEABCmainDEFGIn main,but not in topic
4git log --oneline --graph main..topic* aad429f (topic) C* 6b1eb5a B* d65c129 AtopicDEABCmainDEFGIn topic, but not in main

Git Diff behaviour

1git diff topic..main D E-A-B-C+F+GtopicDEABCmainDEFGwhat's in main whats not in main comparedto topic
2git diff main..topic D E-F-G+A+B+CtopicDEABCmainDEFGwhats in topicwhats not in topic compared tomain
3git diff main...topicDE (you may get newline here)+A+B+CtopicDEABCmainDEFGIn topic,but not in main
4git diff topic...mainDE+F+GtopicDEABCmainDEFGIn main, but not in topic

相关问题