本文首發於公衆號“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
可以看到,目錄就對應一個樹對象,這樣保存目錄的問題就解決了。
數據對象和樹對象用於保存數據和文件名和目錄,我們還需要記錄是誰保存的這些數據以及時間和原因等信息,而這些信息就需要第三個對象——提交對象。下一次我們就來看看提交對象
歡迎關注我的公衆號查看更多精彩文章!