淺談 Git 資料結構
TLDR
.git目錄是 Git 儲存庫的核心,刪除該目錄即等同刪除本機版控。- Git 物件(Blob, Tree, Commit)皆以 SHA-1 哈希值儲存於
objects目錄中。 - 分支與 Tag 本質上只是指向特定 Commit 物件的指標,儲存於
refs目錄。 logs目錄記錄了 HEAD 與分支的變動歷史,可透過git reflog進行誤操作後的還原。index檔案為二進位檔,記錄了git add後的暫存區快照。HEAD檔案記錄當前所在的分支或 Commit 指標。
資料夾結構解析
hooks
存放各種客製化腳本,在 Git 操作(如 commit、push、merge)的特定時機自動觸發。適用於執行自動化測試或程式碼風格檢查。
info
存放輔助性資訊,其中 exclude 檔案用於定義本機排除規則。
- 什麼情況下會遇到這個問題:當開發者需要排除特定檔案,但該規則不應被納入團隊版控時,應使用
info/exclude而非.gitignore。
logs
記錄引用(如 branch、HEAD)的更新歷史,用於追蹤變更紀錄。
- 什麼情況下會遇到這個問題:當執行
git reset --hard或git rebase -i導致 Commit 遺失時,可透過git reflog查詢logs/HEAD內容並進行還原。
objects
儲存所有 Git 資料物件(Blob, Tree, Commit)。
- 結構:以 SHA-1 哈希值的前兩個字元為目錄,後 38 個字元為檔名。
- 物件類型:
- Blob 物件:儲存檔案的實際內容。
- Tree 物件:儲存目錄結構與檔案的 SHA-1 對應關係。
- Commit 物件:儲存提交資訊(包含 Tree 的 SHA-1、父節點 SHA-1、作者與訊息)。
refs
儲存分支與 Tag 的指標,內容為對應的 Commit HASH 值。
- heads:存放本機分支。
- remotes:存放遠端分支。
- tags:存放 Tag 名稱。
檔案結構解析
COMMIT_EDITMSG
記錄上一次 Commit 的訊息內容,供 git commit --amend 或解衝突時編輯使用。
config
儲存該儲存庫的專屬設定,類似於全域的 .gitconfig。
index
記錄最新一次 Commit 後的檔案快照,以及 git add 加入的檔案資訊,為二進位檔案。
HEAD
儲存當前檢出的分支名稱或 Commit HASH。若指向分支,內容格式為 ref: refs/heads/分支名稱。
ORIG_HEAD
記錄進行破壞性操作(如 git reset、git merge)之前的 HEAD 狀態,提供復原路徑。
FETCH_HEAD
標註每次 git fetch 的紀錄。
- 什麼情況下會遇到這個問題:當執行
git fetch後,可透過此檔案查看遠端分支的最新狀態。格式範例如下:
text
3b3a827b86d264f9c81bc77ef6e0e3df5e302ae8 not-for-merge branch 'main' of http://127.0.0.1/wing/Project關於分支的本質
由 Git 的資料結構可知,分支與 Tag 僅是指向特定 Commit 物件的指標。分支會隨每次 Commit 更新,而 Tag 則指向固定的歷史座標。透過追溯 Commit 物件中的父節點資訊,Git 得以構建出完整的歷史版本圖。
TIP
若使用 git reset --hard 刪除了 Commit 記錄,這些節點並不會立即從 objects 資料夾中消失,仍可透過 git reflog 找回。
異動歷程
- 2024-07-31 初版文件建立。
- 2024-09-20 儲存庫根目錄底下的「.gitconfig」無法生效,所以移除可作為版控的相關描述。
