【发布时间】:2010-10-02 13:19:35
【问题描述】:
一些 Git 命令采用提交范围,一种有效的语法是用两个点 .. 分隔两个提交名称,另一种语法使用三个点 ...。
两者有什么区别?
【问题讨论】:
标签: git git-checkout git-diff git-log git-rev-list
一些 Git 命令采用提交范围,一种有效的语法是用两个点 .. 分隔两个提交名称,另一种语法使用三个点 ...。
两者有什么区别?
【问题讨论】:
标签: git git-checkout git-diff git-log git-rev-list
当您将.. 和... 等提交范围与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 一起工作,但现在,您可能想查看What are the differences between double-dot ".." and triple-dot "..." in Git diff commit ranges?。
【讨论】:
这取决于您使用的是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 所做的
git diff 使用点符号。
A...B == A..B + B..A?
git log 这绝对是的
git diff 则相反! git diff A..B == git diff A...B + git diff B...A !
这有点令人困惑 = 所以这是这个流程的实际情况
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 |
topic D E A B C |
main D E F G |
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 |
topic D E A B C |
main D E F G |
Same as above |
| 3 | git log --oneline --graph topic..main * 9411a8b (HEAD -> main) G * 3a567aa F |
topic D E A B C |
main D E F G |
In main,but not in topic |
| 4 | git log --oneline --graph main..topic * aad429f (topic) C * 6b1eb5a B * d65c129 A |
topic D E A B C |
main D E F G |
In topic, but not in main |
Git Diff 行为
| 1 | git diff topic..main D E -A -B -C +F +G |
topic D E A B C |
main D E F G |
what's in main whats not in main compared to topic |
| 2 | git diff main..topic D E -F -G +A +B +C |
topic D E A B C |
main D E F G |
whats in topic whats not in topic compared to main |
| 3 | git diff main...topic D E (you may get newline here) +A +B +C |
topic D E A B C |
main D E F G |
In topic,but not in main |
| 4 | git diff topic...main D E +F +G |
topic D E A B C |
main D E F G |
In main, but not in topic |
【讨论】:
我认为关于两个点与三个点的混淆的最大来源是因为与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.
【讨论】: