回到 Blog

Git Workflow 完整教學
從個人到團隊

Git 學了就忘的核心原因 ─ 你學的是「命令」、不是「workflow」。記命令會忘、理解 workflow 一輩子受用。這篇從個人開發到團隊協作、完整拆解 ─ 分支策略、PR 規範、rebase vs merge、conflict 處理、10 個必學命令。附 cheatsheet。

先建立3 個觀念

01 Git 不是備份工具、是時光機

很多新手把 Git 當「把 code 傳到 GitHub 備份」 ─ 這是把法拉利當腳踏車用。

Git 真正的價值:你能回到任何過去的狀態、能看「誰、什麼時候、為什麼」改了什麼、能同時在多個分支實驗。

02 分支是免費

Git 的 branch 不是「複製整個 project」、是「指針指向某個 commit」。建一個分支只要幾 KB。

所以 ─ 不要怕開分支。實驗一個想法、開分支。修一個 bug、開分支。寫一篇實驗、開分支。

03 Commit 是給未來的你看

現在的 commit message 寫得好不好、決定 3 個月後的你能不能找到「為什麼這段 code 長這樣」。

這跟「commit 短或長」沒關係、跟「寫的人有沒有替未來著想」有關。


個人開發的最簡 workflow

如果你還沒進公司、自己練習用、這個就夠:

# 1. 建好 repo
git init
git remote add origin [email protected]:user/repo.git

# 2. 每次寫新功能、開新分支
git checkout -b feat/login-page

# 3. 寫 code、隨時 commit(重點:commit 頻率高比低好)
git add src/Login.tsx
git commit -m "feat(auth): add login form skeleton"

# 4. 寫完、push 上去
git push -u origin feat/login-page

# 5. 在 GitHub 開 PR、自己 review 自己(是的、自己跟自己 review)
# 6. Merge 回 main

# 7. 刪除本地分支
git checkout main
git pull
git branch -d feat/login-page

重點 ─ 就算只有你一個人、也用 PR 流程

為什麼?因為這逼你「暫停 + 用第三人視角看自己 code」。多數 bug 在 PR 那一刻自己會發現。


團隊開發的3 種 workflow

01 GitHub Flow(最簡單、最常用)

適合:80% 的 web 產品團隊

結構:

  • main ─ 永遠可上線
  • feat/xxxfix/xxx ─ 短生命週期的分支

流程:

  1. main 開分支
  2. 在分支寫 code、commit
  3. push 上去、開 PR
  4. 同事 review + CI 跑過
  5. merge 回 main、自動部署

優點:簡單、適合持續部署。
缺點:沒有「準備上線」的中間狀態。

02 GitLab Flow(適合需要 release 控制)

適合:產品需要分版本上線(如 mobile app、企業軟體)

結構:

  • main ─ 開發中
  • production ─ 線上版本
  • release/v1.2 ─ 特定版本分支

03 Git Flow(複雜、大型專案用)

適合:傳統軟體公司、需要嚴格 release cycle

結構(複雜版):

  • main ─ 線上
  • develop ─ 開發中
  • feature/xxx ─ 功能分支
  • release/xxx ─ 上線準備
  • hotfix/xxx ─ 緊急修復

優點:嚴謹、有專門流程。
缺點:對 web 產品太重、多數小團隊不需要。

建議 ─ 新手用 GitHub Flow、有需要再升級。


分支命名 ─ 有規律

推薦命名 convention:

feat/short-description       # 新功能
fix/short-description        # 修 bug
refactor/short-description   # 重構
docs/short-description       # 文件
test/short-description       # 測試
chore/short-description      # 雜事(升級依賴、設定)

# 範例
feat/oauth-google-login
fix/payment-cancel-bug
refactor/extract-pricing-service
docs/update-readme
chore/upgrade-node-20

好處:

  • 看分支名就知道在做什麼
  • GitHub 排序時類型相近的會聚在一起
  • 跟 commit message 的 type 一致(feat / fix / refactor)

Commit Message ─ 結構化寫法

推薦 Conventional Commits 格式:

<type>(<scope>): <subject>

<body 可選>

<footer 可選>

範例:

feat(auth): add OTP for mobile users

Mobile users were getting locked out due to SMS delivery delays.
Added OTP fallback with 3-minute validity window.

Closes #142

常用 type:

  • feat ─ 新功能
  • fix ─ 修 bug
  • refactor ─ 重構(不改行為)
  • docs ─ 文件
  • test ─ 測試
  • chore ─ 雜事
  • perf ─ 效能優化

這個寫法的好處 ─ 工具可以自動生成 changelog、可以根據 commit 自動 bump version。


Rebase vs Merge ─ 什麼時候用哪個

git merge

合併 2 個分支、保留所有歷史、會多一個「merge commit」。

什麼時候用

  • 合分支回 main(feat → main)
  • 多人協作的 main、避免改寫已 push 的歷史

git rebase

把你的 commits「重新接到」另一個分支的最新狀態、歷史變成一條線。

什麼時候用

  • 把自己的 feature 分支同步到最新的 main、開 PR 前
  • 整理 commit history(squash / reword)

關鍵原則

已 push 上去的、不要 rebase
因為 rebase 會改變 commit hash、別人 pull 過的歷史會錯亂。

所以實務上:

  • 個人 feature 分支(還沒給別人)→ 可以 rebase 整理
  • 共享分支(main / develop / 別人也在用的分支)→ 永遠 merge

處理 Merge Conflict ─ 4 步法

很多新手卡在 conflict、其實有固定流程:

步驟 1:先 fetch 最新

git fetch origin
git status   # 確認當前狀況

步驟 2:拉最新 main 進你的分支

# 如果你還沒 push
git checkout feat/your-branch
git rebase origin/main

# 如果已經 push 過
git checkout feat/your-branch
git merge origin/main

步驟 3:開 editor、看 conflict 標記

Conflict 的檔案會有:

<<<<<<< HEAD
你的版本
=======
別人的版本
>>>>>>> origin/main

選一個保留、或合併兩邊、刪掉 <<<===>>> 標記。

步驟 4:mark resolved + 繼續

git add <檔名>
git rebase --continue   # 如果用 rebase
# 或
git commit              # 如果用 merge

重點 ─ 不確定就 abort

git rebase --abort     # 取消 rebase
git merge --abort      # 取消 merge

回到沒 conflict 前的狀態、想清楚再來。沒人會逼你立刻解決 conflict


10 個你會天天用的命令

命令 用途
git status看現在處於什麼狀態、哪些檔案被改
git diff看當前未 commit 的改動
git log --oneline -10看最近 10 個 commits(精簡版)
git add <檔>把改動加進 staging
git commit -m "msg"提交(最常用)
git checkout -b <分支>建新分支並切過去
git push -u origin <分支>第一次 push 新分支
git pull --rebase拉最新、用 rebase 不產生 merge commit
git stash暫存當前改動、清空 working dir
git reset --soft HEAD~1撤銷上個 commit、但保留改動

進階心法 ─ 5 個

01git rebase -i 整理 history

開 PR 前、把雜亂的 commit 整理成乾淨的:

git rebase -i HEAD~5   # 整理最近 5 個 commits

在編輯器內你可以:

  • pick ─ 保留
  • squash ─ 跟前一個合併
  • reword ─ 改 commit message
  • drop ─ 刪掉這個 commit

這讓你的 PR 看起來像 senior 寫的。

02git stash 切換 task

你正在寫 feature、突然 PM 說「線上有 bug、馬上修」:

git stash                 # 暫存當前改動
git checkout main
git checkout -b fix/urgent-bug
# 修 bug、merge 回 main
git checkout feat/your-feature
git stash pop             # 拿回剛才的改動、繼續寫

這比「亂 commit 一個 WIP」乾淨多了。

03 git bisect 找出哪個 commit 引入 bug

已知 1 週前的 code 沒 bug、今天有了 ─ 不用一個個 commit 看:

git bisect start
git bisect bad             # 當前有 bug
git bisect good <1週前的commit>
# Git 會自動 checkout 中間的 commit、你測試
# 沒 bug → git bisect good
# 有 bug → git bisect bad
# Git 用二分法快速定位到引入 bug 的那個 commit

這個命令在大 codebase 是救命神器。

04 善用 .gitignore.gitattributes

基本的 .gitignore

# Node
node_modules/
.env*
!.env.example

# Editor
.vscode/
.idea/
*.swp

# OS
.DS_Store
Thumbs.db

# Build
dist/
build/
*.log

05pre-commit hook

自動在 commit 前跑檢查(lint、format、test):

# 用 husky + lint-staged(最常見組合)
npm i -D husky lint-staged
npx husky init

# 在 .husky/pre-commit 寫
npx lint-staged

# 在 package.json
"lint-staged": {
  "*.{ts,tsx}": ["eslint --fix", "prettier --write"]
}

設好之後、commit 前自動檢查、避免「我以為改好了結果壞了」。


3 個會嚇新手的情境

01 「我 commit 錯東西進去了」

# 還沒 push
git reset --soft HEAD~1     # 撤銷 commit、保留改動
# 改完再 commit

# 已經 push 了
# 別 git push --force(除非自己分支)
# 用 git revert <commit> 做一個「反向 commit」

02 「我改錯分支了」

# 還沒 commit
git stash
git checkout <對的分支>
git stash pop

# 已經 commit 但沒 push
git checkout <對的分支>
git cherry-pick <那個 commit hash>
git checkout <錯的分支>
git reset --hard HEAD~1    # 移除錯的分支上的 commit

03 「我把 .env 不小心 commit 進去了」

# 立刻換掉 .env 裡的所有 secret(密碼、API key)
# 然後從 history 完全移除

# 用 git filter-repo(推薦)或 BFG Repo Cleaner
git filter-repo --path .env --invert-paths

# 強制 push(這會改寫遠端歷史、團隊要先溝通)
git push --force

重點 ─ 不要假裝沒事。被 commit 的 secret 已經外洩、立刻換掉、然後清歷史。


最後一個提醒

Git 的價值不是學會命令、是養成習慣
每次寫 code 前 ─ 開分支。
每改完 1 件小事 ─ commit。
每個 commit ─ 替未來的自己寫 message。

這 3 個習慣養成 1 個月、你會發現 Git 變成「讓我能放心改 code」的工具 ─ 因為你知道任何錯誤都能回去。

Git 不是工程師需要學的東西、是用工程師方式工作本身。

Git 卡關、想要有人手把手帶?

30 分鐘 1-on-1 諮詢 NT$1,500 ─ 我帶你跑一次完整 workflow、處理你 repo 真的卡的 conflict / rebase 問題。

LINE 預約諮詢 先訂閱 Newsletter