Git是如何保存文件名和目錄關係的---樹對象

本文首發於公衆號「AntDream」,歡迎微信搜索「AntDream」或掃描文章底部二維碼關注,和我一塊兒天天進步一點點git

樹對象(tree)—— 保存文件名和目錄關係

樹對象主要解決2個問題,:文件名的保存和文件目錄關係的保存數據庫

就像下面這樣bash

下面咱們就來模擬一下構建上面這顆樹,也就是模擬保存這3個文件,其中的"bak"是一個目錄,下面有一個文件微信

首先能夠看到,咱們一共須要保存的是3個文件,new.txt 、 內容爲version 2的 test.txt 和內容爲version 1的 test.txt。其中咱們上面已經把version 1的 test.txt寫入到Git倉庫了。ui

Git是怎麼建立樹對象的呢?spa

Git 根據某一時刻暫存區(即 index 區域)所表示的狀態建立並記錄一個對應的樹對象,如此重複即可依次記錄(某個時間段內)一系列的樹對象。而暫存區裏保存就是咱們add進去的文件和目錄。3d

而咱們以前的text.txt是直接存入到Git數據庫裏面了,沒有在暫存區,因此先要把這個文件讀到暫存區裏來code

咱們能夠用 update-index 命令更新暫存區(跟咱們作git add操做是同樣的道理)cdn

git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
複製代碼
  • add :表示寫入,由於文件不在暫存區中
  • cacheinfo:表示是從Git數據庫中取文件,由於咱們的文件不在工做目錄,而是在Git數據庫中
  • 100644:表示是普通文件,此外還有100755,表示一個可執行文件;120000,表示一個符號連接
  • 後面就是文件的SHA-1值和文件名

好的,如今咱們已經把前面的內容更新到暫存區了。對象

而後咱們就能夠用 write-tree 命令生成一個樹對象

git write-tree
//輸出
d8329fc1cc938780ffdd9f94e0d364e0ea74f579
複製代碼

咱們能夠驗證一下它確實是一個樹對象(git cat-file -t命令能夠查看對象的類型):

git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579
//輸出
tree
複製代碼

通過上面的步驟,咱們就把右邊的那個樹對象建立完畢了。

實際上,上面已經解決了一個問題,就是文件名的保存。

git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
//輸出
100644 blob 83baae61804e65cc73a7201a7252750c76066a30	test.txt
複製代碼

這裏咱們再快速建立剩下的部分,直接新建new.txt和更新text.txt,而後用git add添加到暫存區並生成一個新的樹對象

echo 'new file' > new.txt
echo 'version 2'> text.txt
git add .
git write-tree
複製代碼

下面咱們來看看怎麼解決目錄保存的問題,也就是樹和樹關聯起來

//首先把前面的把那個樹對象寫入到暫存區,其中bak就表示目錄名
git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579
//而後生成一個新的樹對象
git write-tree
//輸出
9f2f42e85a6648e5b5f48e1a6f154999e06b9a31
複製代碼

而後咱們就能夠來看看這個新的樹對象了:

git cat-file -p 9f2f42e85a6648e5b5f48e1a6f154999e06b9a31
//輸出
040000 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579	bak
100644 blob fa49b077972391ad58037050f2a75f74e3671e92	new.txt
100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a	text.txt
複製代碼

能夠看到,目錄就對應一個樹對象,這樣保存目錄的問題就解決了。

數據對象和樹對象用於保存數據和文件名和目錄,咱們還須要記錄是誰保存的這些數據以及時間和緣由等信息,而這些信息就須要第三個對象——提交對象。下一次咱們就來看看提交對象


歡迎關注個人公衆號查看更多精彩文章!
複製代碼

AntDream
相關文章
相關標籤/搜索