Git 指令圖解(二):log、tag、分支和合併,每個指令都能按下去看

Git 指令圖解第二篇:log、show、tag,接著是 branch、checkout、merge、cherry-pick 和 rebase。每個指令都能在沙盒裡按下去看提交和分支怎麼動,也順便釐清 HEAD^5、log -1、branch -r 常見的誤解。

Git 指令圖解(二):log、tag、分支和合併,每個指令都能按下去看
Git 指令圖解第二篇封面:有分支、合併和標籤的提交圖
Git 指令圖解第二篇封面:有分支、合併和標籤的提交圖

第一篇講到 add、commit 和 diff,提交已經存進倉庫了。這篇看怎麼讀這些提交,再往下講分支:開分支、切換,以及把別條線的改動拿進來的三種方式。

用法跟第一篇一樣,點指令按鈕看動畫,按「重播」再看一次。圖上的方塊是提交,金色膠囊是分支,藍色虛線膠囊是遠端追蹤分支,綠色是標籤,實心的 HEAD 是你現在所在的位置。終端機輸出照 Git 2.43 的實際格式整理。

看提交歷史

git log 從 HEAD 開始往回走,新的在上面。在沙盒點 git log,圖上的提交會從右到左依序亮起來,就是 Git 走的順序。

互動示範:git log、git show 和 HEAD^、HEAD~ 的差別

這一組有兩個常見的誤解:

  • 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 tag、git show v2.0、git checkout v2.0

git checkout v2.0 會讓 HEAD 直接指著提交,不在任何分支上,Git 會印出一大段 detached HEAD 的說明。看看沒關係,要在那裡改東西就先開分支,也就是下一節的內容。

標籤預設不會跟著 git push 上去,推標籤的方法在第三篇。

分支

Git 的分支只是一個指向提交的名字。開分支、刪分支都只是在動這個名字,提交本身不會被複製或刪除。看沙盒時注意金色膠囊怎麼移動,底下的提交方塊幾乎都沒動。

互動示範:git branch 的各種選項

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 -b、--track 和從遠端開分支

git checkout --track hotfixes/BJVEP933 這樣打會失敗,少了 origin/,要寫成 git checkout --track origin/hotfixes/BJVEP933。現在其實直接打 git checkout hotfixes/BJVEP933 就行,只有一個遠端有這個分支時,Git 會自動建立本地分支並設好追蹤。

合併、挑選、重定

把別人的改動拿進來有三種方式:

  • git merge 把整條分支合進來,兩邊都有新提交時會產生一個合併提交。
  • git cherry-pick 只複製某一個提交。
  • git rebase 把你的提交搬到另一條線的最前面重做一次,歷史會變成直線。
互動示範:merge、cherry-pick、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 --raw
  • git 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:把改動拿進來

上一篇:Git 指令圖解(一):init、add、commit、diff 和復原

下一篇:Git 指令圖解(三):遠端、stash 和救援指令

作者

碼力獅 MaliLion

用 AI 與程式公開打造遊戲、工具和 3D 世界,一次一個 Side Project。

#Git#教學#版本控制#互動圖解
回到所有文章

留言