Git 是開發者用來記錄檔案歷史、回退改動、跟別人協作的版本控制工具,就像是一台時光機。而在 AI Agent 進入日常開發流程之後,這件事變得更嚴重 —— Agent 一次改十幾個檔案是家常便飯,如果沒有 Git 當安全網,開發者連「剛才它到底改了什麼」都說不清楚,更別說反悔。
這篇文章會從 Git 最基本的心智模型開始,帶過日常會用到的指令,再進入分支、reset、stash 等反悔技巧。最後會用一整章談 AI Agent 時代的協作模式,示範如何把 Git 變成跟 Agent 一起工作時的第二層大腦。如果從沒碰過 Git,可以跟著章節順序讀;已經會基礎操作的,可以直接跳到第七章跟第八章。
什麼是 Git
Git 是一套分散式版本控制系統(Distributed Version Control System,簡稱 DVCS),由 Linux 創始人 Linus Torvalds 在 2005 年為了管理 Linux kernel 的原始碼而寫出來。它的核心工作只有一件事:把專案裡的檔案隨時間演化的過程完整記錄下來,並且讓開發者可以在這條時間線上自由來回——回到上週某一個版本、把昨天的改動丟掉、或是把三個人各自寫的功能合併成一份。
AI Agent 普及之後,越來越多 Git 操作其實可以交給 Agent 代勞。Claude Code、Cursor、Copilot Agent 都能自動 stage 檔案、寫 commit message、開 branch、甚至處理簡單的 merge 衝突。但這並不代表開發者可以不懂 Git,就像會計師可以幫公司產生完整的財務報表,老闆自己還是得看得懂報表在說什麼,否則連公司最近有沒有虧錢都判斷不出來。Agent 幫我們敲指令沒問題,但「這次 commit 的範圍對不對」「該不該 reset」「分支該從哪裡切」這些判斷終究是開發者自己要下的。
獨立運行,也能跟遠端伺服器同步
Git 和許多人以為的不一樣:它並不需要 GitHub 才能運作。只要在任何一個資料夾裡執行 git init,就會多出一個 .git/ 目錄,裡面完整保存了整份專案的歷史紀錄。即使永遠不連網、不推到任何伺服器,也可以單靠本地的 Git 做 commit、開 branch、回滾、比對差異,所有版本控制功能都不缺。這正是「分散式」這三個字的意思:每一份 clone 下來的倉庫都是獨立完整的,沒有中央伺服器這種單點依賴。
當需要和別人協作時,才會再接上一個遠端伺服器來同步。最知名的是 GitHub(由微軟收購後成為全球最大的開源社群),其次是 GitLab(可以自架、企業常用)、Gitea(輕量級的自架方案)、Bitbucket 等等。這些平台的共通點是它們都只是 Git 的「遠端倉庫」而已——Git 指令本身完全不需要在意我們用的是哪一家,git push / git pull 在所有服務上都通用。換伺服器就像換信箱,寄信的方式沒有變。
為什麼 AI 時代更需要懂 Git
在傳統的開發流程裡,Git 的主要角色是「團隊協作」與「歷史紀錄」,大部分的 commit 都出自工程師本人之手,每一筆都清楚記得自己做了什麼。但 AI Agent 加入之後情況完全不一樣了:Claude Code、Cursor、Copilot Agent 一次 task 可能修改十幾甚至數十個檔案,有時候還會主動建立、刪除檔案。回過神來想看看改了哪些地方,肉眼比對幾乎不可能。
這時候 Git 從「協作工具」升級成「Agent 的稽核紀錄與安全網」。改動不滿意?git restore 一句就回到原狀。改到一半想暫停做別的?git stash 暫存起來。Agent 把 main 分支搞亂了?在獨立 branch 裡翻車就好,主線完全不受影響。換句話說,Git 熟不熟會直接影響「敢不敢放手讓 Agent 做事」——不懂 Git 的人只敢讓 Agent 改一個檔案,懂 Git 的人敢讓 Agent 同時跑三個 worktree。
安裝與基本設定
Git 在三大作業系統都有官方版本:macOS 上有 Xcode Command Line Tools 內建,也可以用 Homebrew 安裝;Linux 透過套件管理器(apt / dnf / pacman)一行就好;Windows 則建議從 git-scm.com 下載 Git for Windows,它附帶一個 Git Bash 終端機。macOS 使用者如果升級作業系統後突然 Git 不能用,可能是 Command Line Tools 路徑被改掉了,可以參考舊文 更新到 macOS 13 Ventura 之後無法使用 Git、Brew 的解法。
裝完後第一件事是告訴 Git 我們是誰。這個身份資訊會寫進每一個 commit,讓歷史紀錄知道這筆是誰做的。
# 設定使用者名稱與信箱(全域,一次設定即可)
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
# 設定預設分支名稱為 main(現代慣例,取代舊的 master)
git config --global init.defaultBranch main
# 檢查 Git 版本
git --version
# 檢查目前所有設定
git config --list
設定完成後有兩種方式開始一個 Git 專案:git init 把現有資料夾變成 Git 倉庫,或 git clone 把 GitHub / GitLab 上的遠端倉庫抓下來。一般情況下新專案用 init,接手別人的專案用 clone。
Git 的心智模型:三區加一層
很多人學 Git 卡關的主因是沒搞懂「檔案到底住在哪裡」。實際上 Git 把檔案分成三個區域,加上遠端一共四個地方:
- Working Directory(工作目錄):我們實際在資料夾和編輯器裡看到、改到的檔案
- Staging Area(暫存區,又叫 index):即將要 commit 進歷史的檔案快照。這是 Git 最獨特的設計
- Local Repository(本地倉庫):commit 過的歷史紀錄,存在
.git/資料夾裡 - Remote Repository(遠端倉庫):GitHub、GitLab 上那一份
檔案在這四個區域之間流動,就是 Git 日常操作的全部。把這張圖記起來,後面學任何指令都只是在記「它會把檔案從哪裡搬到哪裡」。

其他版本控制工具(例如 Subversion)沒有 staging area 這個概念,直接從工作目錄 commit 到倉庫。Git 多一個 staging area 是為了讓一次 commit 裡只包含我們想要的改動——即使工作目錄裡有十個檔案改了,也可以只挑兩個進 commit。對 AI Agent 時代的開發者來說,這個設計特別重要,後面會再回頭討論。
日常四件事:status、add、commit、log
90% 的 Git 日常操作就是這四件事的排列組合。先看一張時序圖,再逐一講指令。

git status — 看當下狀態
最常用的指令,它會告訴我們:工作目錄改了哪些檔案、哪些已經進 staging、目前在哪個分支、跟遠端有沒有落差。每次下其他指令前建議都先跑一次 git status,避免在不知道自己狀態的情況下亂下指令。
git add — 放進 staging
# 把單一檔案加入 staging
git add README.md
# 把整個目錄的改動加入 staging
git add src/
# 把所有改動加入 staging(新手謹慎使用,容易誤加 .env 等機敏檔)
git add .
# 互動式挑選要加的 hunk(更精細的控制)
git add -p
注意:新手常犯的錯是直接 git add .,結果把 .env、node_modules/、編輯器暫存檔一起加進去。比較安全的習慣是先 git status 看清楚,再用 git add 指定具體檔案或目錄。
.gitignore — 告訴 Git 不要管的東西
為了不讓 git add 誤抓到不該進版控的檔案(密碼、編譯產物、依賴套件、IDE 設定等),專案根目錄可以放一個 .gitignore 檔案,列出要忽略的路徑或 pattern,Git 就會當它們不存在。
# 環境變數(含密碼 / API key)
.env
.env.local
# Node.js 依賴
node_modules/
# 編譯產物
dist/
build/
*.pyc
__pycache__/
# IDE 設定
.vscode/
.idea/
# 作業系統暫存檔
.DS_Store
Thumbs.db
常用 .gitignore 範本可以到 github/gitignore 這個 repo 抓,它依語言、框架、作業系統分類好了。有了 .gitignore 後,git add . 雖然還是偏粗暴,但至少踩到地雷的機率會小很多。
想保留空資料夾:放一個 .gitkeep
Git 只追蹤檔案、不追蹤資料夾,所以空資料夾 git add 下去完全沒反應,clone 到別的機器上也不會存在。但實務上常有需要保留空目錄結構的情境,例如 logs/、uploads/、tmp/cache/ 這種程式啟動時預期要存在、但一開始沒任何檔案的資料夾。
社群慣用做法是在資料夾裡丟一個名為 .gitkeep 的空檔案,讓 Git 有東西可以追蹤、資料夾自然就被保留下來:
# 在空資料夾裡建一個佔位檔
touch logs/.gitkeep
git add logs/.gitkeep
git commit -m "chore: 保留 logs/ 空目錄"
.gitkeep 不是 Git 官方的特殊檔名,純粹是慣例——檔名換成 .keep、PLACEHOLDER 也行,只要那個資料夾裡至少有一個被追蹤的檔案就達到目的。另一種作法是在該資料夾放一個 .gitignore,內容寫成「忽略自己以外的所有檔案」:
# logs/.gitignore
* # 忽略此資料夾內所有檔案
!.gitignore # 但保留 .gitignore 本身
這種寫法的好處是:資料夾保留下來,而且執行時產生的 log、cache 檔案會自動被忽略,不用再到上層 .gitignore 寫一條 logs/*。
git commit — 寫進歷史
# 建立 commit 並直接寫訊息
git commit -m "feat: 新增使用者登入功能"
# 建立 commit 並開編輯器寫訊息(適合寫較長說明)
git commit
# 已經 add 過的檔案,同時 add + commit(只對已追蹤檔案有效)
git commit -am "fix: 修正密碼驗證邏輯"
Commit message 的格式建議遵循 Conventional Commits:以 feat(新功能)、fix(修 bug)、docs(文件)、refactor(重構)、test(測試)、chore(雜項)等前綴分類(後面章節會有詳細介紹),讓歷史紀錄在 git log 看起來有規律,CI 工具也能自動產生 CHANGELOG。
git log — 讀歷史
# 看完整 commit 歷史
git log
# 一行一個 commit,快速瀏覽
git log --oneline
# 圖形化顯示分支結構(加到 .gitconfig 當 alias 很好用)
git log --oneline --graph --all --decorate
# 看某個檔案的歷史
git log -- path/to/file.js
與遠端協作:push、pull、fetch
做到這邊,所有操作都還在本機。要把改動同步到 GitHub 或讓團隊其他人看到,就要進到「遠端」的世界。三個核心指令:push、pull、fetch,差別如下圖。

# 第一次設定遠端(clone 下來的專案會自動有 origin)
git remote add origin [email protected]:user/repo.git
# 把本地的 main 分支推上去(-u 設定上游,之後可以直接 git push)
git push -u origin main
# 從遠端拉取並合併到本地(fetch + merge 的組合技)
git pull
# 只下載遠端的最新狀態,但不自動合併(安全,看到內容再決定)
git fetch
# 查看所有遠端
git remote -v
其實 git pull 背後就是 git fetch 加上 git merge。如果覺得 pull 太粗暴(例如擔心直接合併會有衝突),可以改用 git fetch 先把遠端改動抓下來,用 git log origin/main 看看別人做了什麼,再決定要怎麼合。
遇到衝突怎麼辦
第一次遇到 merge conflict 的開發者通常會嚇一跳,但其實沒那麼可怕。衝突只會發生在「同一個檔案的同一個區域」被兩邊都改了,Git 搞不清楚該留哪個。這時候 Git 會在檔案裡標出衝突區塊:
<<<<<<< HEAD
我的改動版本
=======
對方的改動版本
>>>>>>> origin/main
解法很樸素:打開檔案,手動決定要留誰、或怎麼合併兩邊,然後把 <<<<<<<、=======、>>>>>>> 這三行標記刪掉,最後 git add + git commit 完成合併。VS Code、JetBrains IDE 都有內建的視覺化衝突解決工具,會更直覺。
分支:多線工作的基礎
分支(branch)是 Git 最有價值的功能之一。每開一個新 branch,就等於把當前狀態複製一份獨立運作,彼此互不影響,做完再合回主線。這件事在傳統 SVN 時代很難做到,Git 把它變得幾乎零成本。
個人開發者常以為「我一個人寫 code 不需要分支」,其實剛好相反:個人開發才更需要分支。試驗一個可能失敗的想法、同時開發兩個互斥的功能、或是(重點來了)讓 AI Agent 在隔離環境下工作,分支都是最乾淨的方式。典型的 branch 流程像下圖:

# 看目前有哪些分支(* 代表當前所在分支)
git branch
# 建立新分支但不切過去
git branch feat/login
# 建立並切換到新分支(最常用)
git switch -c feat/login
# 切回 main 分支
git switch main
# 把 feat/login 合併進當前分支
git merge feat/login
# 合併完、分支用不到了就刪掉
git branch -d feat/login
注意:git switch 是 Git 2.23 之後的新指令,用來專門切換分支。舊指令 git checkout 同時負責切換分支跟丟棄檔案改動,語意混亂,現在已經拆成 git switch(切分支)與 git restore(丟棄改動)兩個。很多網路上的舊教學還在寫 git checkout -b,功能一樣但新語法比較清楚。
分支命名慣例
分支名 Git 本身不管,任何合法字串都能當分支名。但團隊協作時如果沒有命名規則,git branch 列出來會變成 fix、temp、kyle-test、new 一堆看不出目的的名字。業界常見的慣例是「前綴+斜線+簡短描述」的形式,像 feat/login、fix/api-timeout,前綴用來標示分支的類型:
| 前綴 | 用途 | 範例 |
|---|---|---|
feat/ | 新功能開發 | feat/google-login |
fix/ | 修 bug | fix/checkout-amount-wrong |
refactor/ | 重構,不改外部行為 | refactor/extract-auth-service |
docs/ | 只改文件 | docs/api-reference |
chore/ | 雜項(依賴升級、設定檔) | chore/upgrade-node-22 |
hotfix/ | 線上緊急修復 | hotfix/payment-500 |
release/ | 準備發版 | release/v2.3.0 |
描述的部分建議用小寫英文+連字號(kebab-case),例如 feat/user-profile-avatar,避免空白、底線、中文字。分支名會出現在指令列、GitHub 網址、CI 工作流 log 裡,純英文 kebab-case 最不容易踩到字元編碼或引號問題。如果公司用 Jira 或 Linear,常見做法是把 ticket 編號接在前綴後面,變成 feat/AUTH-123-google-login,這樣從分支名就能直接對到對應的 ticket。
前綴的選擇其實跟前面提到的 Conventional Commits 是同一套邏輯——當分支前綴與 commit 前綴使用相同詞彙,PR 標題與 CHANGELOG 的分類可以彼此呼應。這個呼應不是強制規範,但採用後整個團隊的歷史紀錄會變得一致。
merge 與 rebase
把一個分支的改動合進另一個分支,有兩種做法:git merge 會產生一個 merge commit,保留兩條歷史平行合流的樣子;git rebase 則把自己的 commit 搬到對方最新的 commit 上,讓歷史看起來像一條直線。
網路上常見「rebase 比 merge 乾淨、一律用 rebase」的說法,其實不完全對。Rebase 本質上是「改寫歷史」,如果分支已經 push 到遠端、別人也拉下來了,再 rebase 會讓協作者的歷史跟遠端對不上,很煩人。實務上的安全守則是:公開歷史用 merge,本地還沒 push 的 commit 可以用 rebase 整理。
反悔技巧:stash、restore、reset、revert
Git 強大的地方在於「幾乎任何操作都可以反悔」。只要改動有被 Git 看過(進過 staging 或 commit),就幾乎不可能真的弄丟。以下四個指令是日常反悔的主力。
git stash — 暫存未完成的工作
場景:手邊改到一半想先切分支做別的事,但現在的改動還不想 commit。
# 把目前工作目錄的改動暫存起來
git stash push -m "進行中的登入功能"
# 看有哪些 stash
git stash list
# 把最近一筆 stash 拿回來
git stash pop
# 拿回特定一筆 stash(不刪除 stash 紀錄)
git stash apply stash@{1}
git restore — 丟棄工作目錄的改動
場景:改了檔案發現越改越亂,想直接回到上一次 commit 的狀態。
# 丟棄單一檔案的未 staged 改動
git restore README.md
# 丟棄所有未 staged 改動(危險,確認後再下)
git restore .
# 把已經 add 的檔案從 staging 拿掉(但保留工作目錄的改動)
git restore --staged README.md
git reset — 回退 commit
git reset 是很多新手搞不清楚的指令,關鍵在於它有 --soft、--mixed、--hard 三種模式,對三個區域的影響完全不同。

# --soft:只把 HEAD 往回移,staging 跟工作目錄不動
# 用途:想把剛才的 commit 拆開重新 commit
git reset --soft HEAD~1
# --mixed(預設):HEAD 往回移、staging 清掉,但工作目錄保留
# 用途:想取消 commit 但保留改動,重新挑選要 commit 的檔案
git reset HEAD~1
# --hard:三個區域全部清掉,回到目標 commit 的乾淨狀態
# 用途:想徹底丟掉 commit 跟所有相關改動(危險!改動會不見)
git reset --hard HEAD~1
注意:--hard 會真的把未 commit 的改動永久丟掉,沒有垃圾桶可以救。下這個指令前務必 git status 確認工作目錄沒有重要改動。另外 reset 只適合用在「還沒 push 到遠端」的 commit,已經公開的歷史請用下面的 revert。
git revert — 安全地「反做」一筆 commit
場景:某筆 commit 已經 push 上去、別人都拉下來了,現在發現有 bug 要還原。revert 會產生一筆新的 commit 來「抵銷」原本那筆,不會改寫歷史。
# 產生一筆新 commit 來反做指定 commit
git revert abc1234
# 反做最近一筆
git revert HEAD

上圖的觀察重點是下排的「檔案狀態」:兩種方法最終的工作目錄都等於 B 的內容,差別在於 歷史的樣子。reset --hard B 把 HEAD 拉回 B、C 從歷史徹底消失,commit 數量變少;revert C 則是新增一筆 D,D 的 diff 正好是 C 的反向,歷史變成 A→B→C→D,commit 數量變多。因此當 C 已經推到遠端(別人本地也有那筆)時只能用 revert——reset 會造成歷史分歧,別人下次 pull 會撞上「非 fast-forward」錯誤。簡單記:本地亂改用 reset,公開歷史用 revert。
AI Agent 時代的 Git 協作
從這章開始進入本文最想分享的內容。Agent(Claude Code、Cursor、Copilot Agent、Aider 等)已經不是純補完工具,而是會自己讀檔、改檔、執行指令的同事。跟這種同事合作,Git 不只是輔助工具,而是協作介面本身。以下七個 pattern 是長期跟 Agent 一起工作後歸納出的實用做法。
Agent 改完先 git diff 再接受
Agent 是同事不是老闆,它的產出值得信任但也要驗證。最便宜的驗證方法就是 git diff:
# 看 Agent 在工作目錄做了哪些未 stage 的改動
git diff
# 看已經 stage 的改動
git diff --staged
# 只看檔案名稱清單,不看詳細內容(先掃一眼改了哪些檔)
git diff --stat
# 只看某個目錄的改動
git diff src/auth/
Agent 寫的 code 常見三種小問題:多加不必要的 import、修到不該修的地方、留下除錯用的 console.log。先跑一次 git diff --stat 看動了哪些檔,再用 git diff 細看邏輯,比直接按「Accept」安全得多。這個習慣養成後,debug 時間會明顯縮短。
另外一個好消息是,現在看 diff 的管道比以前多很多,不一定要在 terminal 裡硬讀。Claude Code、Cursor、Copilot 這類 Agent 工具本身在每次改動後都會直接秀 diff 視窗讓我們確認;VS Code、Antigravity、JetBrains 這類 IDE 都有內建的 Source Control 面板,一鍵就能看到逐檔、逐行的改動並且可以選擇性 stage;Sourcetree、Gitfox、Fork 這類本地 GUI 工具則提供更完整的視覺化比對;推到遠端後,GitHub、GitLab、Gitea 的網頁介面也會直接把 PR 的改動以 side-by-side 或 unified 格式呈現。
小 commit,讓 revert 變成後悔藥
鼓勵 Agent 一次只做一件事,並且頻繁 commit。這樣出問題時,可以精準 revert 那一筆,其他改動全部保留。反過來說,如果讓 Agent 一次改 15 個檔案、最後一個 commit 通通包進去,發現其中一個檔案有問題時只能整筆 revert,連其他 14 個改對的檔案一起丟掉。
實務上可以在 CLAUDE.md、.github/copilot-instructions.md 等 Agent 設定檔裡明確要求「每完成一個獨立步驟就建立一個 commit」,例如「新增 schema」「實作 handler」「補測試」分三筆。關於 Copilot 的設定檔,可以參考 GitHub Copilot Agent 設定教學。
用 git diff 把關,做不做合併由人決定
把 Git diff 看成 code review,建立一個穩定的人機協作迴圈:Agent 提案改動 → 人看 diff → 通過就 commit、不通過就要求 Agent 修,直到滿意為止。這個迴圈如下圖:

迴圈的關鍵是「不要直接把 Agent 的輸出當成最終版本」。即使 Agent 說「我已經完成了、測試都通過」,也建議在 commit 之前看一次 diff、跑一次測試。這不是不信任 Agent,而是知道 Agent 對「完成」的定義可能跟人不同 —— 它可能認為跑過單元測試就叫完成,但沒注意到 integration test 掛了。
用 branch 或 worktree 隔離 Agent 的工作
不要讓 Agent 直接在 main 分支上幹活,開一個 feat/xxx 分支給它,翻車只要 git switch main + git branch -D feat/xxx 就沒事。更進一步,可以用 git worktree 讓多個 Agent 同時在不同分支、不同資料夾並行工作,互不干擾:
# 在 ../project-feat-login 建立新的 worktree,用 feat/login 分支
git worktree add ../project-feat-login feat/login
# 同時在另一個地方開第二個 worktree
git worktree add ../project-feat-payment feat/payment
# 列出所有 worktree
git worktree list
# 用完後移除(注意:不會刪掉 branch)
git worktree remove ../project-feat-login
這樣主資料夾繼續寫 code,同時可以另開兩個終端機,在兩個 worktree 裡各跑一個 Claude Code 或 Cursor session,一個做登入、一個做金流,彼此完全隔離。架構如下:

Worktree 的好處還有:不用頻繁切分支、IDE 可以同時開兩個視窗各看一個功能的 code、Agent 執行長時間任務時不會卡住主工作流程。這大概是 Git 最近幾年被 AI 工具放大價值最明顯的功能。
用 pre-commit hook 攔住 Agent 漏掉的檢查
Agent 常忽略的事情:跑 linter、檢查型別、跑測試。即使 CLAUDE.md 要求「commit 前務必 run tests」,Agent 在忙著解更大問題時還是會忘記。這時候 pre-commit hook 是最後一道防線:
# 在 .git/hooks/pre-commit 建立一個 shell script
#!/bin/sh
# 檢查 lint
npm run lint || exit 1
# 跑測試
npm test || exit 1
# 檢查是否有 console.log 殘留
if git diff --cached | grep -q "console.log"; then
echo "偵測到 console.log,請移除後再 commit"
exit 1
fi
記得給這個檔案執行權限(chmod +x .git/hooks/pre-commit)。更進階的做法是用 pre-commit 框架或 Husky(Node.js 專案),讓 hook 設定可以一起進版控、團隊共用。當 Agent 下 git commit 時 hook 會自動跑,沒通過就擋下來,Agent 看到錯誤訊息後會自己嘗試修。
commit message 讓 Agent 寫,但不要盲信
Agent 很會寫 commit message,省人力。但實測下來有兩個常見坑:
- 分類下錯:明明是 refactor,Agent 誤判成 feat;小修 bug 用 feat 前綴讓 CHANGELOG 看起來一堆新功能
- 過度描述:一筆 commit 只改三行,Agent 寫出一整段解釋,看起來很專業但其實
git log --oneline看不清楚
建議在 CLAUDE.md 裡寫清楚規則:「使用 Conventional Commits、第一行不超過 72 字、只寫 what 不寫 why(why 留給 PR 描述)」。commit 前快速掃一眼 message,前綴不對就改,改完再 commit 並不費事。
用約定式提交(Conventional Commits)讓 Agent 有規則可循
上一節提到的 Conventional Commits(中文常譯作「約定式提交」)是一套替 commit message 加上結構化前綴的慣例,由 conventionalcommits.org 維護規格。格式很簡單:<type>(<scope>): <描述>,例如 feat(auth): 新增 Google 登入。這套慣例的好處在於它讓 commit 歷史可以被機器解析——CI 流程可以自動根據 commit 類型決定要不要觸發 release、CHANGELOG 工具可以自動把 feat 歸到「新功能」、fix 歸到「錯誤修正」,不必手工整理。
常用的 type 就那幾個,記熟之後寫 commit 不太需要思考:
| 類型 | 用在什麼時候 | 範例 |
|---|---|---|
feat | 新增功能(使用者能感知到的) | feat(search): 支援日期區間篩選 |
fix | 修正 bug | fix(auth): 修正 token 過期時未重導向 |
refactor | 重構,外部行為不變 | refactor(api): 抽出 request 驗證邏輯 |
docs | 只動文件 | docs(readme): 補充安裝步驟 |
test | 補測試、調整測試 | test(user): 補齊 email 驗證的邊界測試 |
chore | 雜項(依賴升級、設定檔、工具調整) | chore(deps): 升級 axios 到 1.7 |
perf | 效能改善 | perf(list): 虛擬捲動改善大列表延遲 |
style | 純排版、格式、不影響邏輯 | style: 套用 prettier 格式化 |
ci | CI/CD 相關調整 | ci: 加入 Node 22 測試矩陣 |
Breaking change(破壞性變更)有兩種標記方式:type 後加 !(例如 feat!: 改用新版 API schema),或是在 commit body 加上 BREAKING CHANGE: 說明區塊。兩種都會被解析工具識別,自動把版本號跳到 major。
Agent 寫的 commit message 如果只靠自由發揮,容易每次風格都不一樣——這次 Add login feature、下次 implemented user auth,CHANGELOG 會變成一鍋粥。在 CLAUDE.md、.github/copilot-instructions.md 或 Cursor Rules 裡明確寫「所有 commit message 使用 Conventional Commits 規範、使用繁體中文描述」,Agent 就會穩定產出一致格式。可以在專案根目錄附上一個簡短 cheat sheet 讓 Agent 對照。我們只要在 commit 前快速檢查「type 是不是下對、scope 是不是太大」,大多數情況 Agent 寫的已經能直接用。
反悔組合拳:reset –hard + clean -fd
最後分享當 Agent 把 local 搞得一塌糊塗,最快的復原方式是:
# 回到最近一次 commit 的乾淨狀態(三個區域全清)
git reset --hard HEAD
# 把沒被 Git 追蹤的新檔案跟資料夾也清掉(Agent 亂建的檔案在這步消失)
git clean -fd
# 如果連 .gitignore 裡的也要清(更狠)
git clean -fdx
注意:這個組合非常危險,所有未 commit 的改動都會永久消失。它只適合用在「確認 Agent 的改動不要了、要回到上次 commit 的狀態」的情境。在執行前先 git status 跟 git stash 一下比較安全。但對「Agent 亂改一通我想重來」這個場景,這兩行是最快的。
日常指令速查表
把最常用的指令集中在一張表,寫文章寫到最後連我都要查一下的那種。
| 情境 | 指令 | 備註 |
|---|---|---|
| 看狀態 | git status | 下其他指令前先看一次 |
| 加入 staging | git add <file> | 避免 git add . |
| 建立 commit | git commit -m "..." | 遵循 Conventional Commits |
| 看歷史 | git log --oneline --graph | 建議設成 alias |
| 推上遠端 | git push | 第一次加 -u origin <branch> |
| 拉下遠端 | git pull | 謹慎用,可先 fetch |
| 切換分支 | git switch <branch> | 新指令,取代 checkout |
| 開新分支 | git switch -c <branch> | 建立並切過去 |
| 看改動 | git diff | Agent 產出先看再接受 |
| 丟棄改動 | git restore <file> | 未 staged 的改動 |
| 暫存工作 | git stash | 改到一半要切分支 |
| 回退 commit | git reset --soft HEAD~1 | 保留改動,重寫 commit |
| 反做 commit | git revert <hash> | 公開歷史唯一安全做法 |
| 多 worktree | git worktree add ... | 多 Agent 並行必備 |
學會 Git 之後,AI Agent 才真的變成能放膽使用的工具,而不是每次都擔心檔案被改壞。因此對現在的開發者來說,Git 不再只是「團隊協作工具」,它是跟 Agent 共事時最重要的安全帶、溝通介面,甚至是信任的基礎。指令背後的三區心智模型一旦建立起來,後續只是熟練度問題——每次用到新指令,回到「它把檔案從哪裡搬到哪裡」這個問法,十次有九次能自己推敲出來。