
第一篇講到 add、commit 和 diff,提交已經存進倉庫了。這篇看怎麼讀這些提交,再往下講分支:開分支、切換,以及把別條線的改動拿進來的三種方式。
用法跟第一篇一樣,點指令按鈕看動畫,按「重播」再看一次。圖上的方塊是提交,金色膠囊是分支,藍色虛線膠囊是遠端追蹤分支,綠色是標籤,實心的 HEAD 是你現在所在的位置。終端機輸出照 Git 2.43 的實際格式整理。
看提交歷史
git log 從 HEAD 開始往回走,新的在上面。在沙盒點 git log,圖上的提交會從右到左依序亮起來,就是 Git 走的順序。
這一組有兩個常見的誤解:
git log -1不是「顯示 1 行」,是只顯示 1 筆提交,一筆還是有作者、日期、訊息好幾行。想要一行一筆,用git log --oneline。HEAD^5不是「往回 5 個版本」。^後面的數字是「第幾個父提交」,只有合併提交才有第二個以上的父提交。往回 5 代要寫HEAD~5。
HEAD^ 和 HEAD~1 都是上一個版本,兩者只有在數字變大之後才不一樣。沙盒裡的 git show HEAD~3 可以看到 Git 怎麼一格一格往回數。
標籤
標籤是貼在提交上的名字,不會跟著新提交往前移(除非用 -f 強制重貼),通常用來標版本號。-a 建立的是附註標籤,會記下誰、什麼時候建的,發佈版本建議用它。
git checkout v2.0 會讓 HEAD 直接指著提交,不在任何分支上,Git 會印出一大段 detached HEAD 的說明。看看沒關係,要在那裡改東西就先開分支,也就是下一節的內容。
標籤預設不會跟著 git push 上去,推標籤的方法在第三篇。
分支
Git 的分支只是一個指向提交的名字。開分支、刪分支都只是在動這個名字,提交本身不會被複製或刪除。看沙盒時注意金色膠囊怎麼移動,底下的提交方塊幾乎都沒動。
git branch -r 列出的不是「原創分支」,而是遠端追蹤分支(remote-tracking branch),像 origin/master。它記的是你上次跟遠端同步時,遠端的分支停在哪裡,它不會自己更新,要 fetch、pull 或 push 時才會跟著變。
-d 和 -D 差在檢查。小寫會先確認分支已經合併進它的上游(沒設上游就看目前的 HEAD),沒合併就拒絕;大寫直接刪。刪錯的話,只要你在那個分支上待過,HEAD 的 reflog 通常還找得到它的提交,第三篇會講。
切換與建立分支
git checkout 一個指令身兼好幾種工作,所以新版 Git 拆出了 git switch(切分支)和 git restore(還原檔案)。舊指令照樣能用,網路上的教學也大多寫 checkout,這裡先用 checkout 介紹。
git checkout --track hotfixes/BJVEP933 這樣打會失敗,少了 origin/,要寫成 git checkout --track origin/hotfixes/BJVEP933。現在其實直接打 git checkout hotfixes/BJVEP933 就行,只有一個遠端有這個分支時,Git 會自動建立本地分支並設好追蹤。
合併、挑選、重定
把別人的改動拿進來有三種方式:
git merge把整條分支合進來,兩邊都有新提交時會產生一個合併提交。git cherry-pick只複製某一個提交。git rebase把你的提交搬到另一條線的最前面重做一次,歷史會變成直線。
看 cherry-pick 和 rebase 的動畫時注意 hash:複製或搬過去的提交都拿到新的 hash。所以 rebase 已經推給別人的分支會出事,對方手上是舊提交,你推上去的是新提交,Git 會把它們當成兩份不同的東西。
團隊沒有特別規定的話,我建議先用 merge。歷史雖然多了合併提交,但不會改寫任何人手上的東西;rebase 等你搞清楚哪些提交已經推出去了再用。
這篇的指令速查
git log、-5、--stat、-p -m:看歷史git show <hash>、HEAD、HEAD^、HEAD~3:看單一提交git show -s --pretty=raw:看提交物件的原貌git whatchanged:舊指令,改用git log --rawgit tag、git tag -a、git show <標籤>、git log <標籤>、git checkout <標籤>:標籤git branch、-a、-r、--contains、--merged、--no-merged:列出分支git branch -m、-d、-D:改名、刪除、強制刪除git checkout <分支>、-b <新分支> [起點]、--track origin/<分支>:切換和建立分支git merge、git cherry-pick、git rebase:把改動拿進來

留言