《Git权威指南》读书笔记 第六章 Git对象

6.1 Git对象库git

一次提交有三个拥有哈希值的对象:算法

  • 本次提交;
  • 本次提交所对应的目录树;
  • 贝蒂提交的父提交(上一次提交)。
git log --pretty=format:" "

format中的%H输出本次提交的哈希值;%T输出本次提交对应目录树的哈希值;%P输出父提交的哈希值。分布式

查看哈希值的类型:spa

$ git log --pretty=format:"%H"
326f2370369566e4cacc4c149e612adaba378716
32d79d5cf6e6eac8c95b7978588e4f9db3139a45
4f804c3948640ce146e48f0ff7c4d4592693df87

$ git cat-file -t 326f23
commit

查看哈希值对应commit对象的详细信息:3d

$ git cat-file -p 326f23
tree 76e015495ba4151ac95340f948778d78fa18bb8f
parent 32d79d5cf6e6eac8c95b7978588e4f9db3139a45
author jiangzhi <ivanjz93@163.com> 1468591788 +0800
committer jiangzhi <ivanjz93@163.com> 1468591788 +0800

which version checked in?

查看哈希值对应tree对象的详细信息:版本控制

$ git cat-file -p 76e015
100644 blob b0e5c6e24bc84d489773b2fda5accf005bc912f1    welcome.txt

目录树对象中看到了一个新类型的对象:blob对象,这个对象保存着文件welcome.txt的内容:code

$ git cat-file -p b0e5c6
Hello
Nice to meet you.

上面介绍的这些对象都保存在Git库中的objects目录下面(ID的前两位做为目录名,后38位做为文件名)。使用下面命令查看这些对象在对象库中的实际位置:orm

$ for id in 76e015 32d79d 4f804c b0e5c; do ls .git/objects/${id:0:2}/${id:2}*;done
.git/objects/76/e015495ba4151ac95340f948778d78fa18bb8f
.git/objects/32/d79d5cf6e6eac8c95b7978588e4f9db3139a45
.git/objects/4f/804c3948640ce146e48f0ff7c4d4592693df87
.git/objects/b0/e5c6e24bc84d489773b2fda5accf005bc912f1

能够查看提交对象之间的相互关联:对象

$ git log --pretty=raw --graph 326f23
* commit 326f2370369566e4cacc4c149e612adaba378716
| tree 76e015495ba4151ac95340f948778d78fa18bb8f
| parent 32d79d5cf6e6eac8c95b7978588e4f9db3139a45
| author jiangzhi <ivanjz93@163.com> 1468591788 +0800
| committer jiangzhi <ivanjz93@163.com> 1468591788 +0800
|
|     which version checked in?
|
* commit 32d79d5cf6e6eac8c95b7978588e4f9db3139a45
| tree 1bd6c8f9223ed7d5f8e74af92c561398011ede77
| parent 4f804c3948640ce146e48f0ff7c4d4592693df87
| author jiangzhi <ivanjz93@163.com> 1468585955 +0800
| committer jiangzhi <ivanjz93@163.com> 1468585955 +0800
|
|     who does commit?
|
* commit 4f804c3948640ce146e48f0ff7c4d4592693df87
  tree 1bd6c8f9223ed7d5f8e74af92c561398011ede77
  author ivanjz93 <ivanjz93@163.com> 1468379590 +0800
  committer ivanjz93 <ivanjz93@163.com> 1468379590 +0800

      initialized.

使用:开发

git status -s -b
## master

查看当前工做区的状态精简信息和当前工做分支的名称(-b参数)。

使用下面的命令查看当前的工做分支:

git branch
* master

master前面的*表示这个分支是当前工做分支。git branch命令时分支管理的主要命令。

使用下面三个命令会获得相同的输出:

git log -l HEAD
git log -l master
git log -l refs/heads/master

也就是说在当前版本库中,HEAD、master和refs/heads/master具备相同的指向。

查看.git/HEAD文件的内容:

$ cat .git/HEAD
ref: refs/heads/master

它指向了.git/refs/heads/master。

查看这个文件的内容:

$ cat .git/refs/heads/master
326f2370369566e4cacc4c149e612adaba378716

获得一个哈希值,查看这个哈希值的类型和内容:

$ git cat-file -t 326f23
commit

$ git cat-file -p 326f23
tree 76e015495ba4151ac95340f948778d78fa18bb8f
parent 32d79d5cf6e6eac8c95b7978588e4f9db3139a45
author jiangzhi <ivanjz93@163.com> 1468591788 +0800
committer jiangzhi <ivanjz93@163.com> 1468591788 +0800

which version checked in?

分支master指向的是一个提交ID(最新提交)。能够从.git/refs/heads/master这个文件追踪整个提交历史。

目录.git/refs是保存引用的命名空间,其中.git/refs/heads目录下的引用又称为分支。对于分支,既能够用正规的长格式的表示法,如refs/heads/master,也能够直接用master表示。Git有一个命令git rev-parse能够用于显示引用对应的提交ID:

$ git rev-parse HEAD
326f2370369566e4cacc4c149e612adaba378716

$ git rev-parse refs/heads/master
326f2370369566e4cacc4c149e612adaba378716

$ git rev-parse master
326f2370369566e4cacc4c149e612adaba378716

6.2 SHA1哈希值

一、提交的SHA1哈希值生成方法

(1)首先查看HEAD对应的提交内容:

$ git cat-file commit HEAD
tree 76e015495ba4151ac95340f948778d78fa18bb8f
parent 32d79d5cf6e6eac8c95b7978588e4f9db3139a45
author jiangzhi <ivanjz93@163.com> 1468591788 +0800
committer jiangzhi <ivanjz93@163.com> 1468591788 +0800

which version checked in?

(2)提交信息中总共包含228个字符:

$ git cat-file commit HEAD | wc -c
228

(3)在提交的信息前面加上commit 228<null>,而后执行SHA1哈希算法:

$ (printf "commit 228\000"; git cat-file commit HEAD) | sha1sum
326f2370369566e4cacc4c149e612adaba378716 *-

(4)计算获得的哈希值与用git rev-parse HEAD获得的相同:

$ git rev-parse HEAD
326f2370369566e4cacc4c149e612adaba378716

二、文件内容的SHA1哈希值生成方法

(1)查看版本库中welcome.txt的内容:

$ git cat-file blob HEAD:welcome.txt
Hello
Nice to meet you.

(2)文件总共包含25个字节的内容:

$ git cat-file blob HEAD:welcome.txt | wc -c
25

(3)在文件内容前面加上blob 25<null>的内容,而后执行SHA1哈希算法:

$ (printf "blob 25\000"; git cat-file blob HEAD:welcome.txt) | sha1sum
b0e5c6e24bc84d489773b2fda5accf005bc912f1 *-

(4)计算获得的哈希值与文件的哈希值相同:

$ git rev-parse HEAD:welcome.txt
b0e5c6e24bc84d489773b2fda5accf005bc912f1

三、树的SHA1哈希值计算方法

(1)HEAD对应的树的内容包含39个字节:

$ git cat-file tree HEAD^{tree} | wc -c
39

(2)在树的内容前面加上tree 39<null>,而后执行SHA1哈希算法:

$ (printf "tree 39\000";git cat-file tree HEAD^{tree}) |sha1sum
76e015495ba4151ac95340f948778d78fa18bb8f *-

(3)与树的哈希值一致:

$ git rev-parse HEAD^{tree}
76e015495ba4151ac95340f948778d78fa18bb8f

6.3 不使用顺序的数字表示提交

Git不像SVN那样使用顺序递增的数字表示提交。由于集中式版本控制系统只有一个集中式的版本库,因此能够很容易的实现依次递增的全局惟一的提交号。Git做为分布式版本控制系统,开发能够是非线性的,每一个人均可以经过克隆版本库的方式工做在不一样的本地版本库当中,在本地作的提交能够经过版本局之间的交互(推送和拉回操做)而相互分发,若是提交采用本地惟一的数字编号,在提交分发的时候会出现冲突。这就要求提交的编号是全球惟一的。

SHA1哈希值使得提交编号变得复杂,所以Git提供了不少方法能够方便的访问Git库中的对象:

  • 使用哈希值时能够只写部分,而没必要把40位的哈希值写全,只采用开头的部分,只要不与现有的其余哈希值冲突便可;
  • 使用master表明分支master中最新的提交,也可使用全称refs/heads/master或/heads/master;
  • 使用HEAD表明版本库中最近的一次提交;
  • 符号^能够用于指代父提交,例如:HEAD^表明版本库中的上一次提交,HEAD^^表明HEAD^的父提交;
  • 对于一个提交有多个父提交的状况,能够在符号后面用数字表示第几个父提交,例如:a573106^2表示这个提交的第二个父提交,HEAD^^2表示HEAD^的第二个父提交;(这个地方表述的不清楚,是只祖父提交,仍是一个提交有多个父亲?)
  • 符号~<n>用于指代祖父提交,例如a573106~5至关于a573106^^^^^;
  • 提交所对应的树对象,能够用a573106^{tree}表示;
  • 某一次提交对应的文件对象,能够用a573601:path/to/file访问;
  • 暂存区中的文件对象,能够用:path/tp/file访问。
相关文章
相关标签/搜索