以此历史图表为例:
$ git log --all --graph --oneline
* 691d454 (HEAD -> branch-b) branch-b-2
* c3bd488 branch-b
| * f5756ff (branch-a) branch-a-2
| * de00ec4 branch-a
|/
* 5ad3b15 (root) root
现在,比较git diff branch-a..branch-b
diff --git a/f b/f
index af31a64..e7791f3 100644
--- a/f
+++ b/f
@@ -1 +1 @@
-branch-a-2
+branch-b-2
git diff branch-a...branch-b
diff --git a/f b/f
index d8649da..e7791f3 100644
--- a/f
+++ b/f
@@ -1 +1 @@
-root
+branch-b-2
git log --oneline branch-a..branch-b
691d454 (HEAD -> branch-b) branch-b-2
c3bd488 branch-b
git log --oneline branch-a...branch-b
691d454 (HEAD -> branch-b) branch-b-2
c3bd488 branch-b
de00ec4 branch-a
f5756ff (branch-a) branch-a-2
基本上,我们看到了这个:
|------+--------------------------------------+--------------------------------------|
| | branch-a..branch-b | branch-a...branch-b |
|------+--------------------------------------+--------------------------------------|
| log | root -> branch-b | branch-a -> branch-b |
| | (root, branch-b] | [branch-a, branch-b] |
| | changes introduced in branch-b | difference from branch-a to branch-b |
|------+--------------------------------------+--------------------------------------|
| diff | branch-a -> branch-b | root -> branch-b |
| | [branch-a, branch-b] | (root, branch-b] |
| | difference from branch-a to branch-b | changes introduced in branch-b |
|------+--------------------------------------+--------------------------------------|
这意味着,如果您想要查看在作为提交列表从master中分离的分支中完成的更改,git log master..branch
将向您显示。但是,如果您希望将相同的更改视为组合这些提交的差异,则必须切换到...
,如git diff master...branch
。这是我发现自己经常做的事情,也是我一直想知道的一个小烦恼。
有设计理由吗?这似乎只是一种不一致。
编辑:为了澄清,我知道..
和...
在diff
和log
中的转化为git diff branch-a..branch-b
和git diff $(git merge-base branch-a branch-b) branch-b
。我的问题可以改写为:将它们翻转以使它们彼此保持一致是不是更有意义?例如,如果git diff branch-a...branch-b
表示git diff branch-a branch-b
而diff
表示log
,那么git diff master...branch
将与git log master..branch
一致。那么,为什么不是这样呢?
编辑2:在表格下方的段落中,我给出了master
与branch
类似的实际示例。对于另一种情况,如果要获取将git log master...branch
与git diff master..branch
分开的提交列表(即表示2之间差异的提交),则使用adb pull {absolute path to directory/file}
cat filename
,如果你想要代表相同差异的差异,你可以使用<Type>Code39</Type>
。
编辑3:我试图让桌子更清晰。括号和括号的使用是math interval notation。
编辑4:转换桌子使其更适合。
答案 0 :(得分:0)
他们不是(翻转)。相反,..
中的git diff
具有 no 含义的特殊含义,而...
中的git diff
具有git diff
唯一的特殊含义git diff
1}},在任何其他Git命令中都找不到。
您的特定输入图是 是,在编辑之前:-) ...太小而无法显示真正的差异。如果你在两个分支分歧后有更多的提交,你可以看到更多。
让我们首先看一下git diff
,因为它更简单。 git diff <commit1> <commit2>
在这些特定情况下做了什么 - 组合差异有特殊情况,但它们不适用于此;我们可以将提交与我们的工作树或我们的索引进行区分,我们在这里没有做 - 是选择两个单独的提交并比较它们。
要命名要比较的两个提交,我更愿意写:
git diff <commit1>..<commit2>
但是,如果您愿意,可以写下:
..
这些完全相同的东西,总是。 1 Git只是假装你毕竟没有写master
。无论您在此处使用哈希ID,还是使用origin/master
之类的分支名称,或git diff
之类的远程跟踪名称,或者这些名称的任意组合,都是如此。
请注意,两个提交名称或哈希ID的顺序很重要:git diff <commit1>...<commit2>
的输出是一组指令,告诉您如何更改第一次提交以便获得第二次提交,如果你按照所有说明进行操作。
如果你写:
git diff $(git merge-base <commit1> <commit2>) commit2
Git将仍比较两个提交: 2 Git将在两个给定的提交之间找到 merge base ,然后比较该合并库提交到第二个列出的提交。也就是说,这与shell样式扩展相同:
git diff
这里,和以前一样,顺序很重要:合并基础是相同的, 3 ,无论两次提交的顺序如何,但是合并基础与第二次列出的提交进行比较。 / p>
1 好吧,几乎总是!如果在命令行中列出第三个提交,可以发现一些极端情况,其中它就像您使用三点语法一样。我认为这些是git diff
中的一个错误,尽管有人总是可以依赖它们。
2 这里还有另一个案例,肯定是一个错误:如果有多个合并库,git log
会产生一个组合差异。这不是三点语法的意图,这就是为什么它是一个错误。
3 这假设您没有在脚注2中发现错误。当多个提交有一个合并基础时,顺序无关紧要,但是当存在多个合并基础时,顺序为输入可能会影响输出的顺序。
对于..
和大多数其他Git命令,...
和<commit1>..<commit2>
具有完全不同的含义。毫无疑问,您现在知道<commit2> ^<commit1>
是git rev-parse
的简写。我们可以使用$ git rev-parse master..origin/maint
468165c1d8a442994a825f3684528361727cd8c0
^ccdcbd54c4475c2238b310f7113ab3075b5abc9c
:
origin/maint
此处master
转换为第一个(未取消的)哈希ID,468165c1d8a442994a825f3684528361727cd8c0
转换为第二个(否定的)哈希ID。这些告诉Git,当它遍历提交图时,它应该选择可以从ccdcbd54c4475c2238b310f7113ab3075b5abc9c
(正参考)到达的提交,同时拒绝可以从git log
(负参考)到达的提交。这意味着所有这样的提交,可能是许多提交。像$ git rev-parse master...origin/maint
468165c1d8a442994a825f3684528361727cd8c0
ccdcbd54c4475c2238b310f7113ab3075b5abc9c
^468165c1d8a442994a825f3684528361727cd8c0
这样的命令,遍历提交图,将显示所有选定的提交。
三点符号比较棘手,但内部翻译成同样的正面和负面参考:
origin/maint
这里,两个正面参考是与之前的master
和git merge-base
相关联的哈希ID,而负参考是这些点选择的子图的点的结果 - 积分重新加入。在这个特殊情况下只有一个这样的点 - 所以这与我们将在瞬间看到的$ git merge-base master origin/maint
468165c1d8a442994a825f3684528361727cd8c0
的输出相匹配 - 尽管一些以复杂方式发散和合并的子图可以有多个这样的点:
...
(这些相同类型的复杂图形可以导致多个合并基础,但实现 C--D <-- br1
/
A--B
\
E--F <-- br2
的代码比找到合并基础的代码更简单。)
如果您有这样的图表:
br1...br2
三点语法C-D
选择提交E-F
和git log
用于执行图表的B
,但选择提交F
和{{ 1}}分别用于git diff
(和{em>仅用于git diff
)。双点语法br1..br2
为E-F
等选择提交git log
,并分别对D
的提交F
和git diff
进行比较(和仅 git diff
}。