Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git 为什么此r1..r2修订范围的输出包含可从r2访问的提交?_Git_Git Log - Fatal编程技术网

Git 为什么此r1..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^@ (注意插入符号或帽子后面的@后缀^)。对

在下图中,可以从r2(
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
这里的commit
a562a1983
是一个合并,父级
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
请注意,此图形形状看起来更简单!我已经消除了commit
a562a11983
但没有commit
ad6f028f06
,所以看起来commit
a562a11983
有一个父级,
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日志,那么我们的工作就很容易了。我们从commit
H
开始并显示它。我们现在已经完成了
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
aka
HEAD
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