天天看點

Git是如何儲存檔案名和目錄關系的---樹對象

本文首發于公衆号“AntDream”,歡迎微信搜尋“AntDream”或掃描文章底部二維碼關注,和我一起每天進步一點點

樹對象(tree)—— 儲存檔案名和目錄關系

樹對象主要解決2個問題,:檔案名的儲存和檔案目錄關系的儲存

就像下面這樣

Git是如何儲存檔案名和目錄關系的---樹對象

下面我們就來模拟一下建構上面這顆樹,也就是模拟儲存這3個檔案,其中的"bak"是一個目錄,下面有一個檔案

首先可以看到,我們一共需要儲存的是3個檔案,new.txt 、 内容為version 2的 test.txt 和内容為version 1的 test.txt。其中我們上面已經把version 1的 test.txt寫入到Git倉庫了。

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

Git 根據某一時刻暫存區(即 index 區域)所表示的狀态建立并記錄一個對應的樹對象,如此重複便可依次記錄(某個時間段内)一系列的樹對象。而暫存區裡儲存就是我們add進去的檔案和目錄。

而我們之前的text.txt是直接存入到Git資料庫裡面了,沒有在暫存區,是以先要把這個檔案讀到暫存區裡來

我們可以用 update-index 指令更新暫存區(跟我們做

git add

操作是一樣的道理)

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           

可以看到,目錄就對應一個樹對象,這樣儲存目錄的問題就解決了。

資料對象和樹對象用于儲存資料和檔案名和目錄,我們還需要記錄是誰儲存的這些資料以及時間和原因等資訊,而這些資訊就需要第三個對象——送出對象。下一次我們就來看看送出對象

歡迎關注我的微信公衆号,和我一起每天進步一點點!