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

Posted

技术标签:

【中文标题】Git 提交范围中的双点“..”和三点“...”有啥区别?【英文标题】:What are the differences between double-dot ".." and triple-dot "..." in Git commit ranges?Git 提交范围中的双点“..”和三点“...”有什么区别? 【发布时间】:2010-10-02 13:19:35 【问题描述】:

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

两者有什么区别?

【问题讨论】:

相关:Git diff .. ? What's the difference between having .. and no dots. 【参考方案1】:

在 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 的图表。请注意,命令不会返回两个分支共享的提交:

 

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

您可以使用--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 的提交以&lt; 为前缀,而属于origin/master 的提交以&gt; 为前缀。

在 Git Diff 中使用提交范围

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

另见

Pro Git § 6.1 Git Tools - Revision Selection - Commit Ranges

【讨论】:

这个答案其实用简明的文字、例子和图片来说明区别。我喜欢它比当前投票最多的答案要好得多,后者只是引用了不清楚的文档。 (tl;博士感谢这个答案,我实际上理解了其中的区别。) @Cupcake 你能在 git diff 中添加 off ... 的含义吗? @Marius 实际上,既然你提出来了,我会继续在我的回答中链接到另一个问题,供像你这样的未来读者使用。 这难道不是相反的吗? dig diff a..b 是所有的差异,或者与 git diff a b 基本相同。而 git dif a...b 只是 b 自 a 分支以来所做的更改。 至少对于 git log。对于 git diff 可能情况相反:***.com/questions/7251477/…【参考方案2】:

这取决于您使用的是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 的情况下,它与 git diff A B 相同,只是区分 A 和 B。在 log 的情况下,它显示了所有在 B 中但不在 B 中的提交在 A.

【讨论】:

..... 的含义如何准确地交换为 log 和 diff,这非常荒谬:log A..B 是从合并基础更改为 B,这就是 diff A...B 所做的 @phiresky 是的,可用性真的很差。我建议不要对git diff 使用点符号。 这是否意味着A...B == A..B + B..A @Danon for git log 这绝对是的 @Danon 但对于git diff 则相反! git diff A..B == git diff A...B + git diff B...A !【参考方案3】:

这有点令人困惑 = 所以这是这个流程的实际情况

      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 topicDEABC mainDEFG In topic and main, but not in both
2 git log --oneline --graph main...topic* 9411a8b (HEAD -> main) G* 3a567aa F* aad429f (topic) C* 6b1eb5a B* d65c129 A topicDEABC mainDEFG Same as above
3 git log --oneline --graph topic..main* 9411a8b (HEAD -> main) G* 3a567aa F topicDEABC mainDEFG In main,but not in topic
4 git log --oneline --graph main..topic* aad429f (topic) C* 6b1eb5a B* d65c129 A topicDEABC mainDEFG In topic, but not in main

Git Diff 行为

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

【讨论】:

可能想改变 'master' -> 'main' 以减少混乱【参考方案4】:

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

【讨论】:

以上是关于Git 提交范围中的双点“..”和三点“...”有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

Linux中的双点(..)和单点(.)是啥?

git篇之log

Ruby Restclient 不同的双点或 astrophobe 并且顺序很重要

Cassandra中的双范围查询

郝同学一次通过华为HCIE面试,2.0时代末期的战报

二阶段提交和三阶段提交