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
的提交以<
为前缀,而属于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 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 提交范围中的双点“..”和三点“...”有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章