某些Git命令采用提交范围,一种有效语法是将两个提交名称分隔为两个点..
,另一种语法使用三个点...
。
两者有什么区别?
答案 0 :(得分:533)
当您使用..
和...
等提交范围与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
一起使用添加我自己的解释,但就目前而言,您可能需要查看What are the differences between double-dot ".." and triple-dot "..." in Git diff commit ranges?。
答案 1 :(得分:220)
这取决于您使用的是log
命令还是diff
命令。在log
案例中,它位于man git-rev-parse
文档中:
要排除提交中可到达的提交,请使用前缀^表示法。例如。 ^ r1 r2表示可以从r2到达的提交,但不包括从r1可到达的提交。
此设置操作经常出现 它有一个简写。什么时候 你有两个提交r1和r2(根据语法中解释的语法命名 您可以指定以上修订版) 请求可以访问的提交 来自r2,不包括那些 可以通过“^ r1 r2”从r1到达它 可以写成“r1..r2”。
类似的符号“r1 ... r2”是 称为r1和r的对称差 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
相同,只是对B进行差异A.在log
情况下,它显示B中的所有提交但不包括在A中。
答案 2 :(得分:2)
这有点令人困惑 = 所以这是这个流程的实际情况
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 |
main D E F G |
在topic和main中,但不在 两者 |
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 |
main D E F G |
同上 |
3 | git log --oneline --graph topic..main * 9411a8b (HEAD -> main) G * 3a567aa F |
主题 D E A B C |
main D E F G |
在主要,但不在主题 |
4 | git log --oneline --graph main..topic * aad429f (topic) C * 6b1eb5a B * d65c129 A |
主题 D E A B C |
main D E F G |
在主题中,但不在主要中 |
Git Diff 行为
1 | git diff topic..main D E -A -B -C +F +G< /td> | 主题 D E A B C |
main D E F G |
主要内容 主要内容与主题相比 |
2 | git diff main..topic D E -F -G +A +B +C |
主题 D E A B C |
main D E F G |
主题中的内容 与 主要内容相比,主题中的内容 |
3 | git diff main...topic D E(你可以在这里换行) +A +B +C |
主题 D E A B C |
main D E F G |
在主题中,但不在主要 |
4 | git diff 主题...main D E +F +G |
主题 D E A B C |
main D E F G |
在主要,但不在主题中 |
答案 3 :(得分:2)
假设 A
和 B
是一些提交,所以它们也可以是分支名称、标签等
那么在所有 Git 命令中,A..B
代表范围从 A
到 B
(对于所有 Git 命令) .
而 A...B
具有以下两种含义之一:
其中有意义的范围 A...B
代表从 两者的最后一个共同祖先 到 B
的范围 - 这适用尤其是在 git diff
、git log
或 git rev-list
、
其中范围没有意义但预期单个 commit A...B
表示两个 commits 的最后一个共同祖先。换句话说,它只是较早的提交,如果两者都在同一个分支 或两者的最后一个共同祖先 > 如果 A
和 B
位于不同的分支(在下图中标有 X
) - 这尤其适用于 { {3}}、git checkout
、git branch
或 git switch
。
当 Git 命令可能需要一系列 commits 并且两个 commits 在同一个 branch 上时,两种表示法都表示一样。
我准备了一个图表来说明这两种符号: