# 前言
基本指令外加一些輔助操作,到目前為止應該算是介紹完畢。
在開始進入下一個主題之前的 幾篇 文章,我打算來聊聊一些能承上啟下的觀念。
對… 大概會有一兩篇都是閒聊性質
這些觀念跟指令沒什麼關係,但是如果沒把他搞懂的話,卻會 直接影響 部分指令的操作。
由於筆者不太喜歡在主要內容中穿插各種補充讓文章失焦 雖然已經…,於是乾脆把一些觀念與問題獨立出來聊。
希望大家能因為這幾篇文章更認識 Git ,同時可以在開始介紹其他操作之前,奠定一些概念。
# 聊聊 CommitID
我們再次把這個線圖請出來,並且把關注點放在最右邊的 CommitID 。
這些字母「看起來」很沒意義,不過它卻是我們在用 Git 版控時,十分重要的資訊之一。
這個 ID 其實有一個名字,叫做「哈希值 (hash 值)」(雖然我每次都會念成嘻哈值)。
他是透過密碼學的雜湊函數「哈希函數」所計算出來的值,英文名稱是 SHA-1
(Secure Hash Algorithm 1)。
所以如果讀者在系列文章中,看到 「commitID」、「哈希值」、「SHA」、「SHA-1」,都是在表示這個看起來像亂碼的值。
探討這個值怎麼產出的不是這邊的重點,我們只要知道 Git 在執行 git commit
指令時,會自動針對 Commit 產好哈希值就好。
記得我們把每個 Commit 版本比喻成一筆一筆的「訂單」,那麼這個「哈希值」就可以把他當成「訂單編號」了。
每個 Commit 都會有這個 唯一 (註 1) 的哈希值,好讓我們可以透過它去找到 Commit。
不知道讀者們網購時有沒有使用「訂單編號」的經驗?
例如商品遲遲不出貨,想去問找客服查狀態時,我們就會拎著這個「訂單編號」,問客服這筆訂單是怎麼一回事?
在 Git 的世界也是一樣,當我們想去「操作」某一筆 Commit,就必須要有個依據,讓 Git 知道「那麼多 commit ,是要處理哪一個?」
而這個「哈希值」就是其中一個 (註 2) 能讓 Git 認得 commit 的依據。
註 1. SHA-1 值是有重複的可能性,不過要重複的機率極低,我們幾乎可以當作他就是唯一值。
註 2. 除了 Commit 的 SHA-1 之外,我們也能用 「分支名稱」 ,或是 「
HEAD
」 來找到想取得的 Commit,文末會介紹「相對位置」的找法。
# 取得 CommitID
讀者應該有看過完整的 commitID 的長度,總長大概有 40 個字母之多,如果真的要拿它操作,不太可能慢慢輸入到終端機之中。
Git 因此讓我們輸入前幾個字母即可,只要輸入的值沒跟其他 commitID 開頭重複, Git 就能找到相對應的 Commit。
我們在執行 git log --oneline
指令時,就是只呈現 7 碼 commitID 來給我們使用:
$ git log --oneline -5 | |
c159182 (HEAD -> dev) Merge branch '拉姆' into dev | |
8ec01e1 Merge branch '雷姆' into dev | |
631d193 Merge branch '愛蜜莉雅' into dev | |
4e16000 (Rem) 完成雷姆頁面 | |
b41c499 (Emilia) 完成愛蜜莉雅頁 |
不過,我就懶!我連前面幾個英數字,都懶得慢慢對照 key 到終端機之中,我都直接用複製貼上大法來做這件事。
介紹一下,之後如果要操作 commitID,可以怎麼透過 GUI 複製資料。
# 使用 Fork GUI 取得 CommitID
- 對著那一列 Commit 點右鍵
- 點選 Copy Commit SHA
或是
- 左鍵選到 Commit
- 按
Ctrl
+C
( Mac 應該是Command
+C
,反正就是你我都很熟的複製快捷鍵)
# 在 VSCode Git Graph 套件取得 CommitID
跟 Fork GUI 動作一模一樣!
唯一要注意的是,記得要在「Commit」按右鍵,如果在「分支圖標」按右鍵,會出現操作分支的選項。
此外,這個介面 不支援 鍵盤快捷鍵 ( Ctrl
+ C
),請多加小心。
# 聊聊 HEAD
在執行 git log
指令的時候,會看到這樣的內容: (HEAD -> master):
$ git log --oneline | |
e5f6e37 (HEAD -> master) Initial commit |
這個 master
應該就是「 master
分支」的意思,不過怎麼還有一個 HEAD ->
?
帶大家認識一個 Git 的關鍵詞: HEAD
。
HEAD
是一個「指標」(你可以想像成箭頭),會指著我們「目前所在位置」。
這個 HEAD
在 Fork GUI 中,會用「 ✓
」來表示:
在 Git Graph 則是 「 ○
」:
或是也可以直接看 VSCode 視窗左下角顯示的資訊,也是在提示我們目前所在位置:
HEAD
一般來說是會指著某個分支,像是上圖的例子, HEAD
都是指著 Emilia
分支。
不過如果所在位置沒有分支,他也會直接指著 Commit,例如這樣:
一般來說,在操作 Git 時,不該 是這種狀態!! 觀念將會在【分支篇】說明。
截至目前的文章,我們還沒有建立任何分支的行為,而且也還沒有討論如何讓分支「回到過去」的 commit。
這樣的操作模式下, HEAD
永遠是指著我們唯一的那條分支 master
,而他們都是對應到 最新一次 的 commit。
雖然【一起學 Git 吧!- 分支篇】 還沒開始連載 (?),不過身為作者的我可以先劇透一件事 官方暴雷不可取
當建立新的分支之後,我們是可以讓 HEAD
在不同分支來回移動的,這件事也代表著: HEAD
不會 永遠指在 master
分支上。
也是因為後續 Git 的操作,我們所在位置不一定都是 最新一次 的 commit,所以 Git 才會需要有一個特殊的 HEAD
指標,讓我們能知道自己到底在 「Git 版控樹」的哪個位置上。
# 用 HEAD 尋找相對於目前位置的 commit
前文有示範過怎麼複製特定的 CommitID 回來用,不過未來如果操作的 指令 需要用到 CommitID ,也可以透過用 HEAD
往前推算 commit 的方式,告訴 Git 想要執行哪一個版本。
以這個圖為例子, HEAD
目前是指著 dev
分支:
如果要用 HEAD
對應到先前提交的 Commit 有幾種方式:
-
使用 「
^
」:代表 「上一個」的意思。
目前 HEAD 指著dev
分支,也就是d75c2655
。HEAD^
表示2dbd1a34
。HEAD^^
表示e4c92f3b
。HEAD^^^
表示7f50fc5a
。
-
使用「
~n
」:代表往前 n 筆 commit。HEAD~1
表示2dbd1a34
。HEAD~2
表示e4c92f3b
。HEAD~3
表示7f50fc5a
。
雖然看起來好像很複雜,不過筆者最常使用的相對位置,最多也就到 HEAD^^
,如果要抓更遠的 commitID ,比起操作相對位置,直接用前文說明的操作方式把 commitID 複製出來用可能還比較快呢!
補充:這個操作在 Git GUI 中 用不到,因為這是用「相對位置」的方式告訴 Git 要操作之前的 commit 的語法。
而如果都已經使用 GUI 了,就不要把自己搞得這麼累,還要用「目前位置」往前推算 commit…,直接用滑鼠點擊特定版本操作想執行的動作就可以了!
# 總結
這篇文章稍微介紹一下 commitID 與 HEAD
的觀念,以及取得 commit 的方式。
其中最重要的概念會是,如果有指令需要輸入 CommitID ,也可以使用 「 HEAD
關鍵字操作相對位置」來告訴 Git 想操作的版本。
雖然 GUI 派的使用者可能不太需要知道怎麼操作 HEAD
或複製出 commitID。
不過對兩者有一定程度的認識之後,未來若有相關的動作,能更清楚自己的操作 GUI 的過程,Git 實際是在做什麼事情。
若是指令派的使用者,無論是觀念或是資料的取用,在之後的操作一定會用到,也請多加留意!