我正在使用git log tag1..tag2
查看tag1
和tag2
之间的提交(其中tag1
是旧标记,而tag2
是较新的标记) 。我希望看到tag1
和tag2
之间的提交,但我也看到在tag1
日期之前提交的提交。为什么会这样?
答案 0 :(得分:1)
你遇到的事实是commit1..commit2
并不意味着人们首先认为它意味着什么。实际上,这种表示法只是commit2 ^commit1
的简写。这意味着:查找可从commit2
到达的提交,不包括提交commit1
和可从commit1
到达的提交。
这种“可达”的概念有点棘手。我喜欢把它想象成“油漆暂时提交红色或绿色”。红色意味着停止,绿色意味着像往常一样。我们从最新的提交开始并向后工作。红色油漆覆盖绿色油漆:停止提交保持停止,即使其他东西会让它停止。
考虑像这样的提交图,其中新的提交总是添加在右边:
tag:v2.0
|
v
J1--J2 <-- release/2
/
...--G--H--I--J--... <-- mainline
\
H1--H2--H3--H4--H5 <-- release/1
^ ^
| |
tag:v1.0 tag:v1.1
在这里,我们发布了版本1.0
,1.1
和2.0
(带有v
的标记),这些版本对应于提交H2
,{{1分别是{}和H5
。名称J2
指向mainline
后的某些提交,因此如果我们将名称J
用作绿色/ go,我们将其所有提交降至mainline
,并继续向后到J
,I
,H
等等。我们永远不会“再次”,所以我们永远不会将任何额外的G
或Jn
提交描绘为绿色。同样,如果我们选择Hn
来绘制红色,我们会先绘制H2
,然后H2
,然后H1
和H
,依此类推在左边,但我们永远不会向右移动,所以我们不会触及G
或更右边的任何东西。
查看提交I
,您会看到提交v1.0..v1.1
,然后是H5
,然后是H4
。它们被涂成绿色(从H3
又名v1.1
开始),并且从未涂成红色(从H5
又名v1.0
开始)。查看H2
,您会看到v1.1..v2.0
,然后是J2
,然后是J1
,然后是J
,然后是I
。这一切都很好,可能就是你所期待的。
但这张图非常线性。假设我们在图中有一些fork-and-merge行为:
H
我们选择提交 G--H
/ \
...--E--F K--L <-- branchname
\ /
I--J
开始,L
停止。我们将J
设为红色,J
和I
以及F
等等也都是红色的。然后我们绘制E
绿色,L
绿色,K
绿色和H
绿色。 G
已经是红色(如果我们在绿色之后做红色,则会被红色覆盖)。然后,最后的提交列表是F
,L
,K
和H
,即使在某种意义上G
可能早于{{{} 1}}。诀窍是G
J
不能 G
。 Git根本没有按日期进行:它是通过提交图中的可达性来实现的。
另请参阅my answer至List commits between 2 commit hashes in git,更一般地说,Think like (a) Git。