認識物件的參照名稱
參照名稱 (ref) 簡單來說就是 Git 物件的一個「指標」,或是相對於「絕對名稱」的另一個「好記名稱」,用一個預先定義或你自行定義的名稱來代表某一個 Git 物件。
在我們之前學到的「分支名稱」或我們曾經用過的 HEAD (代表最新版本),或是我們之後會學到的「標籤名稱」,這些都是「參照名稱」,總之就是為了讓你好記而已。
我們以「分支名稱」為例,來說明一下「參照名稱」的實體結構為何。以下圖為例,我們透過 git branch
取得所有分支名稱,你可以看到我們目前有三個分支,然而這三個分支的名稱其實就是一個「參照名稱」,這代表這三個「參照名稱」分別對應到 Git 物件儲存庫中的三個 commit 物件。在下圖中你也可以看出這些分支的參照名稱其實就是一個檔案而已,所有「本地分支」的參照名稱皆位於 .git\refs\heads
目錄下:
接著我再以下圖來證明這個檔案是如何跟「絕對名稱」做連結。我先透過 git branch
取得所有分支名稱,並發現目前「工作目錄」是指向 newbranch1
這個分支。此時我們透過 git log --pretty=oneline
即可取得該分支的所有版本紀錄。預設這些分支的「參照名稱」會指向分支的「最新版」,我們只要打開 .git\refs\heads\newbranch1
檔案的內容,就可以看出這是一個純文字檔而已,而且是指向版本歷史紀錄中的「最新版」。最後再以 git cat-file -p 0bd0
取得該 commit 物件的內容,以及用 git show 0bd0
取得該版本的變更紀錄,藉此證明這些檔案就是「參照名稱」的主要用途。
我們再透過指令看看使用「絕對名稱」與「參照名稱」讀取特定 commit 物件的內容,證明這兩個指令執行的結果是相同的:
在大多數的情況下,「參照名稱」通常都會指向一個 commit 物件,但並非必要,你也可以指向其他 Git 物件類型,像是 blob 物件、tree 物件、tag 物件等等。
認識物件的符號參照名稱 (symref)
符號參照名稱 (symref) 其實也是參照名稱 (ref) 的一種,只是內容不同而已。我們從下圖應可看出其內容的差異,「符號參照」會指向另一個「參照名稱」,並且內容以 ref:
開頭:
在 Git 工具中,預設會維護一些特別的符號參照,方便我們快速取得常用的 commit 物件,且這些物件預設都會儲存在 .git/
目錄下。這些符號參考有以下四個:
- HEAD
- 永遠會指向「工作目錄」中所設定的「分支」當中的「最新版」。
- 所以當你在這個分支執行
git commit
後,這個HEAD
符號參照也會更新成該分支最新版的那個 commit 物件。
- ORIG_HEAD
- 簡單來說就是 HEAD 這個 commit 物件的「前一版」,經常用來復原上一次的版本變更。
- FETCH_HEAD
- 使用遠端儲存庫時,可能會使用
git fetch
指令取回所有遠端儲存庫的物件。這個 FETCH_HEAD 符號參考則會記錄遠端儲存庫中每個分支的 HEAD (最新版) 的「絕對名稱」。
- 使用遠端儲存庫時,可能會使用
- MERGE_HEAD
- 當你執行合併工作時 (關於合併的議題會在日後的文章中會提到),「合併來源」的 commit 物件絕對名稱會被記錄在 MERGE_HEAD 這個符號參照中。