Git中的物件結構(一)

  • 331
  • 0
  • Git
  • 2018-03-29

大概一年前開始在工作上開始使用git做版控, 但是那時候觀念還很模糊,

"總要把這東西的基礎搞懂吧", 那時候心中這樣想著, 於是乎.....終於讓我有比較深入認識的機會了

git裡有四個很重要的物件:

  1. blob物件: 就是工作目錄中某個檔案的"內容"而已, 不包含檔名, 當執行git add加入索引(或稱"暫存區")時, 即產生blob物件
  2. tree物件: 這類物件會儲存特定目錄下的所有資訊,包含該目錄下的檔名、對應的 blob 物件名稱、檔案連結(symbolic link) 或其他 tree 物件等等....tree物件也可包含其他tree物件, 有點類似資料夾的概念。簡單來說, 就是特定版本(commit)下某個資料夾的快照(Snapshot)
  3. commit物件: 用來記錄某個版本(commit)下有哪些tree物件, 作者資訊, commit訊息....等, 除了第一次的版本外, 其他都還會包含上一層的commit物件名稱
  4. tag物件: 是用來關聯特定一個 commit 物件 (也可以關聯到特定 blob、tree 物件),並額外儲存一些額外的參考資訊(metadata)的容器, 如tag名稱: 用來標示某個commit的標籤

 

開一個Hello Git的資料夾,

這幾個物件都會包含在.git/objects的目錄下

blob物件

假設目前在資料夾中新增一個檔案index.html $ echo "Hello, world!" > index.html

再來將此檔案加入索引 $ git add index.html

此時.git/objects目錄底下會多一個為af的資料夾, 此資料夾點開有一個5626b4a114abcb82d63db7c8082c3c4756e51b的檔案(38個字元)

此檔案即為index.html經由SHA-1計算出來的。

驗證一下如果在指令列打上git hash-object index.html就可以得到對應的值, 計算出來為一個40位數的值, 前2個字會當成資料夾名稱, 剩下的38個則當成blob名稱

 

[題外]也可以用指令git cat-file -p af5626b4a114abcb82d63db7c8082c3c4756e51b取得檔案內容

或使用git cat-file -t af5626b4a114abcb82d63db7c8082c3c4756e51b取得該檔是屬於何種物件, 這邊顯示此為blob物件

 

tree物件

建立一個資料夾config, 打上指令mkdir config, 再檢查一下目前目錄的狀態git status

index.html 尚未commit沒錯, 所以它出現Changes to be commited...字樣, 但是剛建立的資料夾config呢? 怎麼沒有顯示Untracked的狀態....

這邊一個重要觀念, git只會對"內容"做SHA-1的計算, 檔案內容完全相同(包含空白)但檔名不同所計算出來的值會相同, config底下完全沒有檔案也沒有內容, 所以連Untracked的狀態都不會有 

 接下來以$ touch config/text.txt在config資料夾下新增一個沒有內容的檔案text.txt讓git感應到, 再看目前狀態會發現出現了(紅字的地方)!!

接下來加入索引 $ git add . , 依前述經驗.git/objects目錄應該會被更動多一個test.txt對應的blob物件,  以下列的圖來看, 產生了一個e6開頭的資料夾,

再以指令計算$ git hash-object test.txt證明此為計算出來的blob物件

進行commit  開始介紹tree物件, 前面有說過tree物件是儲存特定目錄下的所有資訊, 所以以下才會開始談到tree物件。

運行commit指令後, 5d6f33d就是commit物件, 稍後再來說明, 先說明4e和67開頭的資料夾

先觀察一下資料夾, 依修改日期排序出現了紅框中的3個資料夾

先來看一下4e開頭的這個資料夾, 是一個tree物件

再取得檔案內容git cat-file -p 4eaf58fb6efefdf3b208b2997504653e0faaf380, 其中包含一個text.txt對應的blob物件, 所以應該類似資料夾config

剩一個67開頭的資料夾, 直接上結果, 它是一個tree物件, 包含了config資料夾及同層的index.thml, 所以應該是根目錄對應的tree物件

以底下這張圖來統整目前結果

 

下一段, commit物件及tag物件請看 Git中的物件結構(二)