《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訪問。
相關文章
相關標籤/搜索