让我们来看看输出git show
。 (这是一个真正的回购实际输出,虽然我会剪掉大部分位。)
$ git show d362e62
commit d362e62490dd7f59c170a0a050a203fa0eda9f5a
[snip]
diff --git a/fmt.py b/fmt.py
index c44c267..ba772ee 100755
[snip]
这里,d362e62
是“短版”的承诺,即,它的SHA-1的真名。 “长”形式是完整的40个字符的版本,这是git show
输出的第一行。
除了提交文本,提交本身含有“树”(零个或多个“父母”)。我们可以git cat-file -p
看到:
$ git cat-file -p d362e62
tree 0b9bebfee8890b242875af0df209fd9f335bf14d
parent 41f3a6bcba1f5f7059133f862727809f49ff4657
[snip author, committer, and commit text]
我们可以看一下“树”为好。我可以使用上面的“真实名称”SHA-1,但在这里我使用了一些git语法:提交标识符^{tree}
告诉git从提交ID中提取树ID。
$ git cat-file -p d362e62^{tree}
[snip]
120000 blob 7417b50d02819bbebeac0f4104850549935f7089 fmt
100755 blob ba772eeb6139de5a724d67d18ce01bfccaf57590 fmt.py
[snip]
我留在管道为fmt
,因为它是一个符号链接fmt.py
。符号链接的模式为120000
,它告诉git blob
数据实际上是符号链接的目标。文件fmt.py
的模式为100755
,它告诉git它是一个普通的文件并且它是可执行的(它是一个Python脚本)。 这是您在index
行中看到的100644
或100755
的来源。
团块(文件对象)的“真名”在GIT回购是40个字符的SHA-1。 fmt.py
的7个字符的缩写版本为ba772ee
。 这是在上线index
两个..
- 分隔号码秒数。
在该行的第一号是“真名”中的以前版本的文件,Git的回购即,fmt.py
那是在回购之前的版本,我创建提交d362e62
。
我们可以使用特殊的git语法的另一位看到这些孩子的。 作为记录在gitrevisions,之后提交说明符的帽子字符(抑扬,向上箭头,不管你喜欢称呼它)^
告诉混帐找到犯下的第一个父。所以:
$ git rev-parse d362e62^
41f3a6bcba1f5f7059133f862727809f49ff4657
告诉我们承诺提交之前我给git show
是一个名为41f3a6b...
。而且,果然,如果我们git cat-file -p
,我们得到另一个犯了另一棵树,如果我们git cat-file
那棵树-ID,并查找fmt.py
我们会发现另一个blob
与另一SHA-1:
$ git cat-file -p 41f3a6b
tree cbfb63beec96eebf0c73ba6a501cc8151adfec8a
parent 80eeb496ea3f538aa14acdc6b0815024a5e99c7e
[snip]
$ git cat-file -p cbfb63beec96eebf0c73ba6a501cc8151adfec8a | grep fmt.py
100755 blob c44c267c4603838ac7a54aa450b33d0dd7a8bebc fmt.py
$
还有它是:cc4c267
是存储在之前的提交中的文件的“真实名称”的缩写形式。 这是行中的第一个号码。
我把这一切全部写出来以说明git如何从“A点”到“B点”。但是,就像用短手语法d362e62^{tree}
,有一个很简单的方法来获取BLOB使用git rev-parse
SHA-1的值:
$ git rev-parse d362e62:fmt.py
ba772eeb6139de5a724d67d18ce01bfccaf57590
$ git rev-parse d362e62^:fmt.py
c44c267c4603838ac7a54aa450b33d0dd7a8bebc
如果你想缩短的版本,使用git rev-parse --short
截断SHA- 1值为(通常)7个字符。
所以:
而且我想知道哪些commit
产生的补丁,以及如何解析的补丁15 index e220f68..e611b24 100644
?
的15
是行号你(或有人的地方)加入,现在你知道什么是价值观上的index
线其余都是。但是要找到提交-这很困难。 提交是发现其他值。没有将“其他值”链接回“提交”:“箭头”只是指向提交到树,然后从树到斑点。没有从斑点到树的指针,也没有从树到提交的指针。
Git总是以某种外部指定名称开始。通常这是一个分支名称或标签,或者是一个“符号参考”(通常是HEAD
,如果没有“分离头”)。该引用查找提交。 如果引用是分支名称,则该提交是该分支的“提示”。 如果它是一个标签,它仍然会发现一个提交。如果是HEAD
和HEAD
是master
之类的分支的名称,git只是将HEAD
转换为master
,然后将master
转换为提交。换句话说,提交是您开始的地方,通常是从名称到提交ID,但您几乎总是可以在此指定一个“原始”SHA-1 ID。
一旦git有一个提交ID,该提交标识更多的提交(它的父母)和一棵树。如果需要,该树标识子树,并且该树及其子树标识斑点。从具有“外部名称”的所有提交开始,git最终会查找所有树和所有blob,并且存储库中的所有树或Blob都是而不是,如果以这种方式发现,则可以使用git gc
(或当git gc
自动运行)。 (这是如何删除分支,以及git在内部创建的任何数量的特殊临时文件,都会在稍后进行清理。)
Git有特殊语法的很多。最有用的记忆,在我看来:以后的事情=父
- 帽子:
master^
=
- 波浪 “
master
的父母” 和编号N
之后的事情=备份N
父母:master~2
= “的master
祖父母”
X..Y
=“由Y
选择所有修订,但不包括所有版本选择由X
“:git log master..devel
=‘登录分支devel
所有提交使不上master
’
的..
语法也用于git diff
,但在这里,而不是”东西上Y
这不是X
“,您可以直接比较与X
相关的版本与Y
相关的版本。
我故意跳过“带注释的标签”,它也有存储库实体。在某些情况下,git将访问标签对象,而在其他情况下 - 当需要提交时,树和/或blob-git将自动跟随带注释的标签。在内部,注释标签看起来与提交非常相似,除了代替树和父项外,它具有对另一个git存储库对象的引用 - 通常直接指向提交,但有时指向另一个标签,理论上可以创建为树或blob注释标记,完全跳过提交部分。
分支名称始终指向其自己分支的尖端,但该分支可能只是另一分支的一部分。举例来说,假设你有提交的一个很好的线性序列:
...<-- C3 <-- C4 <-- C5 <-- C6 <-- C7
其中C7拥有C6作为其母公司,C6有C5,等等。如果分支标签X
是对提交C5
的引用,则分支X在C5处结束。如果分支标签Y
指向C7,则分支Y在C7处结束。在这种情况下,分支Y“包含”分支X,但反之亦然。