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

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

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

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

就像下面這樣

下面我們就來模擬一下構建上面這顆樹,也就是模擬保存這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

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

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


                           歡迎關注我的公衆號查看更多精彩文章!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章