什麼是 Git 中的樹?

Back
Category : News

喺 Git 入面,樹 (tree) 係一個好重要嘅概念,佢同 Git 點樣管理同儲存檔案有直接關係。如果你有玩開 Git,應該知道 Git 唔係好似傳統嘅版本控制系統咁,只係追蹤檔案嘅改動,而係會為你嘅項目每次提交 (commit) 建立一個完整嘅快照 (snapshot)。而樹就係呢啲快照嘅核心組成部分,幫 Git 將檔案同資料夾嘅結構同內容連繫起來。

簡單黎講,Git 嘅樹係一個物件,用來表示一個目錄 (directory) 嘅結構同內容。佢包含咗一堆指向其他樹或者 blob(檔案內容嘅二進制物件)嘅參考,仲有相應嘅檔案名同權限資訊。喺 Git 嘅物件資料庫(通常位於項目根目錄嘅 .git/objects/ 路徑),樹同 blob、commit 等物件一齊,組成咗 Git 點樣儲存同管理你嘅項目嘅基礎。

一個樹物件好似一個目錄清單,佢會記錄咗目錄入面所有檔案同子目錄嘅資訊,包括:

  • 檔案名:每個檔案或者子目錄嘅名稱;
  • 物件類型:指明係 blob(檔案)定係另一個樹(子目錄);
  • SHA-1 哈希值:用來指向對應嘅 blob 或樹物件;
  • 檔案權限:例如係咪可執行檔案(好似 100644 代表普通檔案,100755 代表可執行檔案)。

透過呢啲資訊,Git 可以將一個特定版本嘅項目結構同內容完整還原。例如,當你執行 git checkout 切換到某個提交,Git 會根據嗰個提交指向嘅樹物件,重構你嘅工作目錄,確保檔案同目錄嘅結構同內容同提交時一模一樣。

樹同 blob 嘅關係好似檔案系統同檔案內容嘅關係。Blob 只儲存檔案嘅內容,唔包含檔案名或者路徑資訊。而樹就負責將呢啲 blob 同檔案名、目錄結構連繫起來。舉個例,假設你嘅項目有以下結構:

project/
├── file1.txt
├── file2.txt
└── subfolder/
└── file3.txt

喺 Git 入面,呢個結構會被表示為一個樹物件,當中包含咗指向 file1.txtfile2.txt 嘅 blob 物件,以及一個指向 subfolder 嘅子樹物件。而 subfolder 嘅子樹又會指向 file3.txt 嘅 blob 物件。呢種層次結構讓 Git 可以高效咁管理複雜嘅項目。

樹物件喺 Git 嘅運作中仲有幾個重要嘅作用。首先,佢哋係 Git 提交 (commit) 嘅基礎。一個提交物件會指向一個頂層樹物件,呢個樹物件再遞歸指向其他子樹同 blob,從而表示整個項目喺嗰一刻嘅狀態。其次,樹物件讓 Git 可以快速比較不同提交之間嘅差異。例如,當你用 git diff 比較兩個提交,Git 會比較佢哋指向嘅樹物件,搵出檔案內容或者結構上嘅改動。

另外,樹物件仲幫 Git 實現咗高效嘅儲存同壓縮。因為 Git 會用 SHA-1 哈希值來識別每個樹同 blob,如果唔同嘅提交有相同嘅檔案內容或者目錄結構,佢哋可以共用同一個 blob 或樹物件,節省儲存空間。呢個設計係 Git 點樣做到高效版本控制嘅關鍵之一。

想深入了解樹物件,你可以試下用 git cat-file -p 指令去檢查一個樹物件嘅內容。例如,搵到一個提交嘅 SHA-1 哈希值,然後用 git cat-file -p <commit-hash> 睇吓佢指向嘅樹,再用同一個指令睇樹嘅內容,會見到檔案名、權限同指向嘅物件哈希值。呢啲操作可以幫你更好咁理解 Git 點樣組織同儲存資料。

總括黎講,Git 嘅樹物件係一個好重要嘅結構,負責將檔案同目錄嘅資訊同實際內容連繫起來,係 Git 快照系統嘅核心。明白樹嘅作用,可以幫你更深入理解 Git 嘅運作原理,仲可以喺使用 Git 時更得心應手。想知更多關於 Git 嘅內部運作,可以參考 initialcommit.com 嘅詳細文章。