提交ID
在介绍暂存区的时候,使用过git log --pretty=oneline
命令,会得到以下输出
$ git log --pretty=oneline
5782fe225003c2bc481d554ddeeab8fecd0dd19d (HEAD -> master) third change
0789463b17be77ffe8da6fbc7e4b7777d065008c which version checked in?
ac01ff39a78fa388e1e628754fd55a76feb358d2 init hellogit file
上面三行输出前面的三个40位十六进制的魔幻数,这就是提交ID,这些个数其实就是SHA1哈希值
上面这条命令仅仅是简要输出日志,使用下面的命令可以详细查看git log --pretty=raw
$ git log --pretty=raw
commit 5782fe225003c2bc481d554ddeeab8fecd0dd19d
tree 9c0665f333400ef615ea572bd006dca8408c0579
parent 0789463b17be77ffe8da6fbc7e4b7777d065008c
author smxknife <2323937771@qq.com> 1522171984 +0800
committer smxknife <2323937771@qq.com> 1522171984 +0800
third change
commit 0789463b17be77ffe8da6fbc7e4b7777d065008c
tree 2ac6d09bdc7a46221bb25f1d2c6446924a0bd96a
parent ac01ff39a78fa388e1e628754fd55a76feb358d2
author smxknife <2323937771@qq.com> 1522171550 +0800
committer smxknife <2323937771@qq.com> 1522171550 +0800
which version checked in?
commit ac01ff39a78fa388e1e628754fd55a76feb358d2
tree ced33498fd91fb4cfc1c05d101a9571d0fda4f50
author smxknife <2323937771@qq.com> 1522165085 +0800
committer smxknife <2323937771@qq.com> 1522165085 +0800
init hellogit file
同样显示了三次提交日志,但是每次日志丰富了很多
- commit 本次提交的ID
- tree 本次提交对应的目录树
- parent 上一次提交ID,可以看一下第一个parent与第二个commit是一样的
cat-file 研究提交ID的重量级武器
每次的提交id虽然很长,但是呢在使用的时候不需要40位全部使用,只要保证不重复,写个四五六七位都可以,现在就用cat-file来研究一下这些ID到底有什么用,代表什么意思
$ git cat-file -t 5782fe
commit
$ git cat-file -t 9c0665
tree
$ git cat-file -t 078946
commit
从输出结果上看,根据这些id输出都是日志前面的类型,所以,-t的用处是显示ID对应的类型,下面再用-p(用来查看ID的内容)参数来进行查看
$ git cat-file -p 5782fe
tree 9c0665f333400ef615ea572bd006dca8408c0579
parent 0789463b17be77ffe8da6fbc7e4b7777d065008c
author smxknife <2323937771@qq.com> 1522171984 +0800
committer smxknife <2323937771@qq.com> 1522171984 +0800
third change
commit的ID里面存储的是上面的内容,再看一下tree的ID里面存的是什么内容
$ git cat-file -p 9c0665
100644 blob 990080f5544293a6409c0d32f06b6d98b506b0bd hellogit
这里出现新的类型:blob,看一下后面的Id的类型是否是blob
$ git cat-file -t 9900
blob
再看一下blob的内容吧
$ git cat-file -p 9900
Hello Git.
new change
third change.
熟悉亲切,这正是我们亲手写入hellogit文件中的内容,所以git上真正的文件内容是存在blob对象里。
那这些对象到底是存在哪里呢?
.git/objects目录
见名知意,objects目录正是git存放对象的目录,进去看看
$ cd .git/objects
$ ls -al
total 0
drwxr-xr-x 13 ShaoYun staff 416 3 28 01:33 .
drwxr-xr-x 13 ShaoYun staff 416 4 2 21:27 ..
drwxr-xr-x 3 ShaoYun staff 96 3 28 01:25 07
drwxr-xr-x 3 ShaoYun staff 96 3 28 01:25 2a
drwxr-xr-x 3 ShaoYun staff 96 3 28 01:33 57
drwxr-xr-x 3 ShaoYun staff 96 3 28 01:32 99
drwxr-xr-x 3 ShaoYun staff 96 3 28 01:33 9c
drwxr-xr-x 3 ShaoYun staff 96 3 27 23:38 ac
drwxr-xr-x 3 ShaoYun staff 96 3 28 00:41 c4
drwxr-xr-x 3 ShaoYun staff 96 3 27 23:38 ce
drwxr-xr-x 3 ShaoYun staff 96 3 27 23:35 d9
drwxr-xr-x 2 ShaoYun staff 64 3 27 23:28 info
drwxr-xr-x 2 ShaoYun staff 64 3 27 23:28 pack
???这都是些什么,看不懂,不要紧,往上翻,找到blob对应的ID是990080f5544293a6409c0d32f06b6d98b506b0bd
,前两位是99,目录列表中正好有99目录,进入...
$ cd 99
$ ll
total 8
drwxr-xr-x 3 ShaoYun staff 96 3 28 01:32 .
drwxr-xr-x 13 ShaoYun staff 416 3 28 01:33 ..
-r--r--r-- 1 ShaoYun staff 46 3 28 01:32 0080f5544293a6409c0d32f06b6d98b506b0bd
又出现了一串数字!!!仔细看,加上前面的99,是不是与blob对应的ID相等。觉得不靠谱,再查一个,第一个commit对应的ID,肯定一样
所以,git对象的真正存储方式我们已经找到了,每个提交ID其实就是git对象对应的存储目录和文件名,前2位是目录,后38位是文件名,对应的内容都是存在这个38位的文件里
HEAD和master有什么区别和联系
这里需要先了解一下分支命令,输入git branch
$ git branch
* master
显示分支,这里只有一个分支master,前面的*代表当前工作的分支,由此说明master是一个分支
现在输入以下三个命令,看输出结果
$ git log -l HEAD
commit 5782fe225003c2bc481d554ddeeab8fecd0dd19d (HEAD -> master)
Author: smxknife <2323937771@qq.com>
Date: Wed Mar 28 01:33:04 2018 +0800
third change
commit 0789463b17be77ffe8da6fbc7e4b7777d065008c
Author: smxknife <2323937771@qq.com>
Date: Wed Mar 28 01:25:50 2018 +0800
which version checked in?
commit ac01ff39a78fa388e1e628754fd55a76feb358d2
Author: smxknife <2323937771@qq.com>
Date: Tue Mar 27 23:38:05 2018 +0800
init hellogit file
$ git log -l master
commit 5782fe225003c2bc481d554ddeeab8fecd0dd19d (HEAD -> master)
Author: smxknife <2323937771@qq.com>
Date: Wed Mar 28 01:33:04 2018 +0800
third change
commit 0789463b17be77ffe8da6fbc7e4b7777d065008c
Author: smxknife <2323937771@qq.com>
Date: Wed Mar 28 01:25:50 2018 +0800
which version checked in?
commit ac01ff39a78fa388e1e628754fd55a76feb358d2
Author: smxknife <2323937771@qq.com>
Date: Tue Mar 27 23:38:05 2018 +0800
init hellogit file
$ git log -l .git/refs/heads/master
commit 5782fe225003c2bc481d554ddeeab8fecd0dd19d (HEAD -> master)
Author: smxknife <2323937771@qq.com>
Date: Wed Mar 28 01:33:04 2018 +0800
third change
commit 0789463b17be77ffe8da6fbc7e4b7777d065008c
Author: smxknife <2323937771@qq.com>
Date: Wed Mar 28 01:25:50 2018 +0800
which version checked in?
commit ac01ff39a78fa388e1e628754fd55a76feb358d2
Author: smxknife <2323937771@qq.com>
Date: Tue Mar 27 23:38:05 2018 +0800
init hellogit file
这三个命令的输出结果完全一致。
首先解释一下,git分支有以下两种表示方法
- 正规的长格式表示法:refs/heads/master
- 简单表示法(我自己起的名):master
那么上面三个命令的后两个一样就完全可以理解,一个东西,内容肯定是一样的
现在看HEAD和master
进入.git目录查看内容,目录下有个HEAD文件,查看一下文件内容
$ cat HEAD
ref: refs/heads/master
了然,HEAD其实就是指向了一个引用,而这个引用地址为master的地址,所以,三者输出完全一样,没毛病
再看一下master里面的内容
$ cat .git/refs/heads/master
5782fe225003c2bc481d554ddeeab8fecd0dd19d
熟悉的ID,与上面的日志对比一下看到,就是最新一次的commit ID,有了这个id,我们就可以追踪整个提交历史了
目录.git/refs是用来保存引用的命名空间,其中refs/heads目录下的为分支目录
为什么采用40位SHA1
40位的ID是很长,为什么不采用svn那种递增式增长序列呢?
这就涉及到git的设计思想了,git是一种分布式管理方式,这就需要一个全球唯一的ID才能做到不重复,而SHA1做到了基本上全球唯一,很难出现重复的情况,这样可以避免版本冲突的问题
rev-parse
git rev-parse master
这是git的一个底层命令,可以用来查看引用对应的提交ID,而不需要像我们之前一样要访问到分支文件下的文件查看
git rev-parse HEAD
使用HEAD代表版本库最近的一次提交
git rev-parse HEAD^
加一个“\^”号,代表最新一次提交的父提交,后面可以加多个\^,如果想要找到10次提交之前的,总不能加10个\^吧,是的,这很不优雅,可以在\^后面跟数字,表示第几个父提交git rev-parse HEAD^2
表示第二个父提交
还有另一种写法~<n>
,如 5782~5
,相当于5782^^^^^
提交所对应的树对象可以用以下语法访问
5782^{tree}
PS: 更多文章可以访问https://www.smxknife.com
共同学习,写下你的评论
评论加载中...
作者其他优质文章