Git 为什么此r1..r2修订范围的输出包含可从r2访问的提交?
在下图中,可以从r2(Git 为什么此r1..r2修订范围的输出包含可从r2访问的提交?,git,git-log,Git,Git Log,在下图中,可以从r2(HEAD)和r1(75ec2933~1)访问最后两个提交 我不得不在这里猜测一下(更新:已确认),但我认为我们有这种情况: Commit75ec2933是一种合并提交,即有两个父级 父项#1有一些未知的哈希ID(更新:887b3cfa) 父项2是2effd96f 如果是这种情况,表达式75ec2933~1..HEAD将排除父项1,但不排除父项2。您可以通过运行以下命令找到答案: git rev-parse 75ec2933^@ (注意插入符号或帽子后面的@后缀^)。对
HEAD
)和r1(75ec2933~1
)访问最后两个提交
我不得不在这里猜测一下(更新:已确认),但我认为我们有这种情况:
- Commit
是一种合并提交,即有两个父级75ec2933
- 父项#1有一些未知的哈希ID(更新:
)887b3cfa
- 父项2是
2effd96f
75ec2933~1..HEAD
将排除父项1,但不排除父项2。您可以通过运行以下命令找到答案:
git rev-parse 75ec2933^@
(注意插入符号或帽子后面的@
后缀^
)。对于生成的git日志
输出,有一个相当长的解释。不过,为了演示它,我将使用Git存储库来代替Git本身,因为这是我手边的一个存储库
例子
下面是我在Git存储库中对Git执行不同合并提交时发生的情况:
$ git rev-parse a562a11983^@
7fa92ba40abbe4236226e7d91e664bbeab8c43f2
ad6f028f067673cadadbc2219fcb0bb864300a6c
这里的commita562a1983
是一个合并,父级7fa92ba40a
和ad6f028f06
如果我在git的git存储库上运行git日志--decoration--oneline--graph
,允许git日志
从提交b5101f9297
开始(一个旧的master
tip-我已经好几个星期没有更新git存储库了),结果如下:
* b5101f9297 (HEAD -> master) Fourth batch after 2.20
* a562a11983 Merge branch 'it/log-format-source'
|\
| * ad6f028f06 log: add %S option (like --source) to log --format
* | 7fa92ba40a Merge branch 'js/add-e-clear-patch-before-stating'
|\ \
| * | fa6f225e01 add --edit: truncate the patch file
* | | 371820d5f1 Merge branch 'bc/tree-walk-oid'
|\ \ \
| * | | 974e4a85e3 cache: make oidcpy always copy GIT_MAX_RAWSZ bytes
| * | | ea82b2a085 tree-walk: store object_id in a separate member
| * | | f55ac4311a match-trees: use hashcpy to splice trees
| * | | 36775ab524 match-trees: compute buffer offset correctly when splicing
| * | | 0a3faa45b1 tree-walk: copy object ID before use
| | |/
| |/|
* | | a6e3839976 Merge branch 'jt/upload-pack-deepen-relative-proto-v2'
使用git log--decoration--oneline--graph a562a11983^1..HEAD
将其修剪为:
* b5101f9297 (HEAD -> master) Fourth batch after 2.20
* a562a11983 Merge branch 'it/log-format-source'
* ad6f028f06 log: add %S option (like --source) to log --format
请注意,此图形形状看起来更简单!我已经消除了commita562a11983
但没有commitad6f028f06
,所以看起来commita562a11983
有一个父级,ad6f028f06
,即使它实际上有两个。实际上,git log--graph
对我们撒了谎。
长的
在深入研究git log
本身的细节之前,还需要注意一些事项。首先,中的语法r1..r2
,相当于r2^r1
。事实上,如果我们使用git rev parse
来扩展语法,这正是我们看到的:
git rev-parse a562a11983^1..HEAD
b5101f929789889c2e536d915698f58d5c5c6b7a
^7fa92ba40abbe4236226e7d91e664bbeab8c43f2
* 91cc860a (HEAD -> topic)
* 1048e4d1
* 1c28716e
HEAD
是以b5101
开头的提交哈希,a562a1983^1
(后缀^
和数字1)是以7fa92b…开头的提交…
注意,我们在这里使用插入符号^
作为后缀,而不是前缀;插入符号作为前缀意味着不排除修订,但插入符号作为后缀引入了许多其他gitrevisions说明符之一,例如@
,{commit}
,当然还有特定父项的数字选择
另一个事实是,每个提交记录零个或多个父哈希ID。大多数提交只有一个父ID。您在存储库中进行的第一次提交没有父ID,原因很简单,它不能有任何父ID:新提交的父ID必须是现有的有效提交哈希ID。没有父级的提交称为根提交。一些提交(通常是由git merge进行的提交)有两个父级,您可以进行具有三个或更多父级的多臂octopus合并。根据定义,任何具有两个或多个父哈希ID的提交都是合并提交
由于大多数提交都有一个父级,因此我们通常从此类提交链的末尾开始,通常由分支标签(如master
)标记,然后我们可以一次向后执行一个提交:
... <-F <-G <-H <-- master (HEAD)
如果我们想模拟git日志,那么我们的工作就很容易了。我们从commitH
开始并显示它。我们现在已经完成了H
,所以我们返回到它的父级G
。我们显示G
,然后返回F
。我们重复这个过程,直到我们到达一个根提交,这个根提交没有父级,允许我们停止,或者直到用户退出git log
但假设我们有一个具有合并提交的图:
I--J
/ \
...--H M--N <-- master (HEAD)
\ /
K--L
我们有三个出发点,即develope
(f4a483cc
)、topic
,以及HEAD
(75ec2933~1
是对某些散列ID的否定引用)。结果是,HEAD
和topic
都是名称提交91cc860a
,因此队列中只有两个提交
--graph
选项稍微修改了优先级队列。默认情况下,具有最高日期(即,最远的将来,或至少在过去)的提交位于队列的前面。对于--graph
或--topo order
,相同的规则已就位,但添加了一个附加规则:在显示其所有子项之前,不能显示父提交。在这种情况下,由于91cc860a
和f4a483cc
没有父/子关系,该额外异常在此时不起作用
因此,git log
从这两个日志中日期较晚的一个开始,即91cc860a
akaHEAD
和topic
。Git使用单个*
打印此提交,并找到进入队列的父级1048e4d1
1048e4d1
也比f4a483cc
更新,所以Git接下来会显示它。它是上一次提交的直接父级,因此现在是显示该提交的时候了。这将持续一段时间,以便我们看到:
git rev-parse a562a11983^1..HEAD
b5101f929789889c2e536d915698f58d5c5c6b7a
^7fa92ba40abbe4236226e7d91e664bbeab8c43f2
* 91cc860a (HEAD -> topic)
* 1048e4d1
* 1c28716e
1c28716e
具有父级c7a197bd
,c7a197bd
是f4a483cc
的祖先,因此无论其日期如何,都不能显示。Git现在开始显示f4a483cc
,这是一个普通的提交:
| * f4a483cc (develop)
f4a483cc
的父级是b7cb53e6
因此b7cb53e6
进入队列。该提交具有c7a197bd
作为祖先,因此Git显示b7cb53e6
下一步:
| * b7cb53e6
。。。而b7cb53e6
本身就是一个合并,将其父级| * f4a483cc (develop)
| * b7cb53e6
| |\
| |/
|/|
* | c7a197bd
* | 3935a1a7
| * ad27a1fc
| |\
| |/
|/|
* | 75ec2933 Merge branch 'develop'
| * 5e55f38f
|/
* 2effd96f <--------------- ???
|/|
* | 75ec2933 Merge branch 'develop'
|\|
| |\
| * | 5e55f38f
|/ /
* | 2effd96f
* | ae6c987e
* | ecc2b546