您好,登錄后才能下訂單哦!
git對象庫是Git版本庫實現的核心,它包含了原始數據文件和所有的日志信息、作者信息、日期,已經其他用來重建項目任意版本或者分支的信息。位于.git/objects目錄下。
├── HEAD
├── branches
├── config
├── description
├── hooks
│ ├── pre-commit.sample
│ ├── pre-push.sample
│ └── ...
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
git對象庫中有四種類型:塊(blob)、目錄樹(tree)、提交(commit)、標簽(tag)。這四種原子對象構成了Git高層數據結構的基礎。
git對象的尋址使用40位的16進制數表示,也就是SHA1或者散列碼,例如7f8aacaddffe009fff75b81187527c35a51f3eac。為了管理方便在文件系統中前兩位作為文件夾的名字,后38為作為文件名字。
你可能感覺用40位作為git對象的尋址ID,可能會存在不同的內容但是散列碼相同的情況,你的感覺是正確的,但是這種情況出現的概率肯定可以忽略不計了。
其對象的關系如下:
blob對象存儲文件的時間內容,實際為工作空間的文件內容。具體為對文件內容使用zlib算法壓縮,然后對得到的字節取hash算法。因此相同的文件內容,得到的blob對象肯定是相同的。
示例:
git init temp -----初始化一個空的git倉庫
cd temp
echo "Welcome to git">hello.txt
git add hello.txt ------添加到暫存器
此時我們查看.git/objects的目錄如下:
此時我們可以通過git cat-file命令查看git對象的內容。注意cat-file命令可以查看所有的git對象。這個命令可以查看所有的git對象。
git cat-file -p b08a2810d8a4542f350f650435f506c6c81ca9b2
Welcome to git
由于git對文件內容使用壓縮然后對內容取hash作為文件名的特性,因此不管文件系統中同樣文件內容有幾份,在git對象中都僅僅存一份。
git目錄樹對象映射操作系統中工作空間的目錄,不同的是工作空間的目錄下是文件和文件夾的集合,而目錄樹對象則為blob對象和目錄樹對象的集合。
mkdir src
cd src
cp ../hello.txt hello.txt
git add hello.txt
git write-tree -----git的內部命令,commit命令基本等于write-tree 和commit-tree命令
此時我們使用write-tree命令返回的hash值使用cat命令
從圖中可以看出內容相同的文件,blob是相同的,命令樹tree對象是對應文件系統的文件夾的一個映射。
提交是我們使用git的時候經常的動作,每一個提交都執行了一個目錄樹對象。同時提交也有一個或者多個父提交。我們現在使用commit-tree命令來關聯目錄樹對象吧(一般使用commit命令來自動創建樹對象和關聯父提交)。
我們可以使用git $command --help來查看命令的資料文檔,例如git commit --help 、git pull --help
git commit-tree 5657a3b1d1454667d51f8c64c1fe9830276cdcea -m "1 commit" ----初次提交所以沒有指定父提交
7df70363051681bdd078b6a1a3fc9fe3d1595325 ----返回commit對象的HASH值
git cat-file -p 7df70363051681bdd078b6a1a3fc9fe3d1595325
tree 5657a3b1d1454667d51f8c64c1fe9830276cdcea
author xxxxxxx <xxxx@163.com> 1516538936 +0800
committer xxxx <xxxx@163.com> 1516538936 +0800
1 commit
注意此時當我們使用git log命令并不會顯示剛剛的提交,需要使用 git merge 7df70363051681bdd078b6a1a3fc9fe3d1595325命令合并到master分支。可以看出git commit命令基本等于write-tree commit-tree merge命令。
現在我們修改工作空間中的hello.txt命令,然后提交查看目錄樹的內容。
注意看tree對象和第一次提交隊對應的tree對象相同,都是e15a40c68bd15301b60d21c204a5e7a87d62d8a1,而本身我們也沒有修改其文件夾下面的任何內容。而blob對象32690ead83f3b77ad763e9e2c2e60ce3706cf117的內容是兩行,說明git對象內部提交指定的tree對象是工作空間的一個快照,而不是存儲的增量(否則內容就是剛剛添加的一行了)。
標簽僅僅是一個提交的快照,而且不允許修改其內容。
$ git tag 1.0
$ git cat-file -p 1.0
tree f935b24b9a688ba5050fda30d70801c9092caeaa
parent 7df70363051681bdd078b6a1a3fc9fe3d1595325
author xxx <xxx@163.com> 1516542403 +0800
committer xxx <xxx@163.com> 1516542403 +0800
2 commit
git的blob對象使用字節流進行存儲,因此不存在編碼問題。
對于目錄樹對象對應的路徑、commit對應的message注釋,默認都使用UTF-8編碼。
如果想修改編碼格式請參照(除非有特別的理由):https://git-scm.com/docs/git-commit/1.8.0.1#_discussion
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。