Git 两个标签之间的日志显示提交早于标签?
Git log between two tags showing commits older than tags?
我正在使用 git log tag1..tag2
查看 tag1
和 tag2
之间的提交(其中 tag1
是旧标签,而 tag2
是较新)。我希望看到在 tag1
和 tag2
之间进行的提交,但我也看到了在 tag1
日期之前进行的提交。为什么会这样?
您 运行 明白 commit1..commit2
并不像人们最初认为的那样。事实上,这个符号只是 shorthand for commit2 ^commit1
。这意味着:查找可从 commit2
访问的提交,排除提交 commit1
和可从 commit1
.
访问的提交
这个"reachable from"概念有点棘手。我喜欢将其视为 "paint commits red or green temporarily"。像往常一样,红色表示停止,绿色表示走。我们从最新的提交开始并向后工作。红色油漆覆盖绿色油漆:停止提交保持停止状态,即使其他东西会让它继续。
考虑像这样的提交图,其中新提交总是添加在右侧:
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
、H5
和 J2
分别。名称 mainline
指向 J
之后的某个提交,因此如果我们将名称 mainline
用作 green/go,我们将其所有提交都归结为 J
,并且继续向后 I
、H
、G
等。不过,我们从不 "go right again",所以我们从不将任何额外的 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
,然后是 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
,尽管在某种意义上 G
可能早于 J
。诀窍在于 G
无法从 J
访问。 Git 根本不按日期进行:它按提交图中的可达性进行。
另见 my answer to List commits between 2 commit hashes in git, and more generally, Think like (a) Git。
我正在使用 git log tag1..tag2
查看 tag1
和 tag2
之间的提交(其中 tag1
是旧标签,而 tag2
是较新)。我希望看到在 tag1
和 tag2
之间进行的提交,但我也看到了在 tag1
日期之前进行的提交。为什么会这样?
您 运行 明白 commit1..commit2
并不像人们最初认为的那样。事实上,这个符号只是 shorthand for commit2 ^commit1
。这意味着:查找可从 commit2
访问的提交,排除提交 commit1
和可从 commit1
.
这个"reachable from"概念有点棘手。我喜欢将其视为 "paint commits red or green temporarily"。像往常一样,红色表示停止,绿色表示走。我们从最新的提交开始并向后工作。红色油漆覆盖绿色油漆:停止提交保持停止状态,即使其他东西会让它继续。
考虑像这样的提交图,其中新提交总是添加在右侧:
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
、H5
和 J2
分别。名称 mainline
指向 J
之后的某个提交,因此如果我们将名称 mainline
用作 green/go,我们将其所有提交都归结为 J
,并且继续向后 I
、H
、G
等。不过,我们从不 "go right again",所以我们从不将任何额外的 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
,然后是 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
,尽管在某种意义上 G
可能早于 J
。诀窍在于 G
无法从 J
访问。 Git 根本不按日期进行:它按提交图中的可达性进行。
另见 my answer to List commits between 2 commit hashes in git, and more generally, Think like (a) Git。