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

时间:2009-01-20 20:32:19

标签: git git-diff git-log

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

两者有什么区别?

4 个答案:

答案 0 :(得分:533)

使用提交范围和Git日志

当您使用.....等提交范围与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" diagram Tree 1

这些是git log A...B的图表。请注意,命令不会返回两个分支的 共享 提交:

"git log A...B" diagram Tree 2

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

通过使用...选项显示哪些提交属于哪个分支,您可以使三点提交范围--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?

另见

答案 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)

无论使用哪种特定的 Git 命令,这两种表示法都很容易解释。

假设 AB 是一些提交,所以它们也可以是分支名称标签

那么在所有 Git 命令中,A..B 代表范围从 AB(对于所有 Git 命令) .

A...B 具有以下两种含义之一:

  • 其中有意义的范围 A...B 代表从 两者的最后一个共同祖先B 的范围 - 这适用尤其是在 git diffgit loggit rev-list

  • 其中范围没有意义但预期单个 commit A...B 表示两个 commits 的最后一个共同祖先。换句话说,它只是较早的提交,如果两者都在同一个分支 或两者的最后一个共同祖先 > 如果 AB 位于不同的分支(在下图中标有 X) - 这尤其适用于 { {3}}、git checkoutgit branchgit switch

当 Git 命令可能需要一系列 commits 并且两个 commits 在同一个 branch 上时,两种表示法都表示一样

我准备了一个图表来说明这两种符号:

git show