在我們初學 git 時,遇到的指令有 git add
、git commit
、git branch
、 git push
等等,再透過 git status
與 git log
等指令,就可以觀察剛剛做的事情造成的影響。
然而,下完這些指令到底是「如何造成變化」的,我們不得而知、也確實不用真的知道就可以讓專案進行下去,這些指令被稱為對使用者友善的「上層指令(porcelain commands)」,其字面意思是「瓷器指令」,可以想成廁所馬桶,瓷器(還有附著在瓷器上的)部分是給人用的,我們只要按下沖水鈕,就可以沖馬桶,完全不必知道按下沖水紐之後,馬桶內部發生了什麼事。
至於「底層指令(plumbing commands)」,字面意思為「管路指令」,再以馬桶為例,就可以想成那些被瓷器包起來的管路,唯有實際接觸管路,我們才得以看到內部運作,並從中做更細微的操作與調整,不再只是單純沖水完等水箱補水而已。
上層與底層指令類比對照(圖片取自維基百科)
回到前一篇文提到的範例,我們知道:
git add
git commit
這兩個是上層指令,git add
是把檔案先放到預存區(staging area)、git commit
是形成一筆 commit 快照(snapshot)。至於:
git hash-object
git update-index - add
git write-tree
git commit-tree
git update-ref HEAD
這些就是底層指令,其作用分別為:
git hash-object
:產生一組 blob 物件,並計算物件 ID。git update-index - add
:把第 1. 步產生的 blob 物件放進預存區。git write-tree
:把預存區的檔案拿來做出 tree 物件。git commit-tree
:從指定的 tree 物件建立 commit 物件。git update-ref HEAD
:把 HEAD 這個參考(reference)指向 4. 做出來的 commit 物件。怎麼越解釋越看不懂,那一堆奇奇怪怪的物件是什麼?參考又是什麼?緊接著下一篇,我們將一同探索一個 commit 的內部結構。
Git 的指令分兩種,一是上層的「瓷器」指令,對使用者較友善;二是底層的「管路」指令,可以操作比較底層的細節。