git-workflow

git-workflow

熱門

Git 工作流程模式,包含分支策略、提交規範、合併與 rebase、衝突解決,以及適合各種規模團隊的協作開發最佳實務。

23萬星標
3.5萬分支
更新於 2026/7/17
SKILL.md
readonlyread-only
name
git-workflow
description

Git 工作流程模式,包含分支策略、提交規範、合併與 rebase、衝突解決,以及適合各種規模團隊的協作開發最佳實務。

Git 工作流程模式

Git 版本控制、分支策略與協作開發的最佳實務。

何時啟用

  • 為新專案設定 Git 工作流程
  • 決定分支策略(GitFlow、主幹開發、GitHub Flow)
  • 撰寫提交訊息與 PR 描述
  • 解決合併衝突
  • 管理發行版本與版本標籤
  • 帶領新團隊成員熟悉 Git 實務

分支策略

GitHub Flow(簡單,推薦多數團隊使用)

最適合持續部署與中小型團隊。

main(受保護,隨時可部署)
  │
  ├── feature/user-auth      → PR → 合併至 main
  ├── feature/payment-flow   → PR → 合併至 main
  └── fix/login-bug          → PR → 合併至 main

規則:

  • main 隨時可部署
  • main 建立功能分支
  • 準備好審查時開啟 Pull Request
  • 審查通過且 CI 通過後,合併至 main
  • 合併後立即部署

主幹開發(高速度團隊)

最適合具備強大 CI/CD 與功能開關的團隊。

main(主幹)
  │
  ├── 短期功能分支(最多 1-2 天)
  ├── 短期功能分支
  └── 短期功能分支

規則:

  • 所有人直接提交至 main 或極短生命週期的分支
  • 功能開關隱藏未完成的功能
  • CI 必須通過才能合併
  • 每天部署多次

GitFlow(複雜,以發行週期為導向)

最適合排程發行與企業級專案。

main(正式發行版本)
  │
  └── develop(整合分支)
        │
        ├── feature/user-auth
        ├── feature/payment
        │
        ├── release/1.0.0    → 合併至 main 與 develop
        │
        └── hotfix/critical  → 合併至 main 與 develop

規則:

  • main 僅包含可上線的程式碼
  • develop 是整合分支
  • 功能分支從 develop 建立,合併回 develop
  • 發行分支從 develop 建立,合併至 maindevelop
  • 修補分支從 main 建立,合併至 maindevelop

何時使用哪種策略

策略 團隊規模 發行頻率 最適合
GitHub Flow 任何規模 持續 SaaS、網頁應用、新創公司
主幹開發 5 人以上有經驗 每天多次 高速度團隊、功能開關
GitFlow 10 人以上 排程 企業、受監管行業

提交訊息

慣例提交格式

<類型>(<範圍>): <主題>

[可選內文]

[可選頁尾]

類型

類型 用途 範例
feat 新功能 feat(auth): add OAuth2 login
fix 錯誤修正 fix(api): handle null response in user endpoint
docs 文件 docs(readme): update installation instructions
style 格式調整,無程式碼變更 style: fix indentation in login component
refactor 程式碼重構 refactor(db): extract connection pool to module
test 新增/更新測試 test(auth): add unit tests for token validation
chore 維護任務 chore(deps): update dependencies
perf 效能改善 perf(query): add index to users table
ci CI/CD 變更 ci: add PostgreSQL service to test workflow
revert 還原先前的提交 revert: revert "feat(auth): add OAuth2 login"

好範例 vs 壞範例

# 壞:模糊,無上下文
git commit -m "fixed stuff"
git commit -m "updates"
git commit -m "WIP"

# 好:清楚、具體,說明原因
git commit -m "fix(api): retry requests on 503 Service Unavailable

外部 API 在尖峰時段偶爾會回傳 503 錯誤。
已加入指數退避重試邏輯,最多重試 3 次。

Closes #123"

提交訊息範本

在儲存庫根目錄建立 .gitmessage

# <類型>(<範圍>): <主題>
# # 類型:feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# 範圍:api, ui, db, auth 等
# 主題:祈使語氣,句尾無句號,最多 50 字元
#
# [可選內文] - 說明原因,而非內容
# [可選頁尾] - 重大變更、關閉 #issue

啟用方式:git config commit.template .gitmessage

合併 vs Rebase

合併(保留歷史)

# 建立合併提交
git checkout main
git merge feature/user-auth

# 結果:
# *   合併提交
# |\
# | * 功能分支提交
# |/
# * main 提交

使用時機:

  • 將功能分支合併至 main
  • 想要保留完整歷史
  • 多人共同開發該分支
  • 分支已推送且他人可能基於此分支開發

Rebase(線性歷史)

# 將功能分支的提交重新建立在目標分支之上
git checkout feature/user-auth
git rebase main

# 結果:
# * 功能分支提交(已改寫)
# * main 提交

使用時機:

  • 用最新的 main 更新本地功能分支
  • 想要線性、乾淨的歷史
  • 分支僅存在本地(尚未推送)
  • 只有你一個人在該分支上工作

Rebase 工作流程

# 用最新的 main 更新功能分支(在 PR 之前)
git checkout feature/user-auth
git fetch origin
git rebase origin/main

# 解決任何衝突
# 測試仍應通過

# 強制推送(僅限你是唯一貢獻者)
git push --force-with-lease origin feature/user-auth

何時不該使用 Rebase

# 絕對不要對以下分支使用 rebase:
- 已推送至共用儲存庫的分支
- 他人已基於此分支開發的分支
- 受保護分支(main、develop)
- 已合併的分支

# 原因:Rebase 會改寫歷史,破壞他人的工作

Pull Request 工作流程

PR 標題格式

<類型>(<範圍>): <描述>

範例:
feat(auth): add SSO support for enterprise users
fix(api): resolve race condition in order processing
docs(api): add OpenAPI specification for v2 endpoints

PR 描述範本

## 內容

簡要說明此 PR 做了什麼。

## 原因

說明動機與背景。

## 方式

值得強調的關鍵實作細節。

## 測試

- [ ] 新增/更新單元測試
- [ ] 新增/更新整合測試
- [ ] 已執行手動測試

## 截圖(如適用)

UI 變更的前後截圖。

## 檢查清單

- [ ] 程式碼符合專案風格規範
- [ ] 已完成自我審查
- [ ] 複雜邏輯已加入註解
- [ ] 文件已更新
- [ ] 未引入新的警告
- [ ] 測試在本機通過
- [ ] 已連結相關議題

Closes #123

程式碼審查檢查清單

審查者:

  • [ ] 程式碼是否解決了所述問題?
  • [ ] 是否有未處理的邊界情況?
  • [ ] 程式碼是否可讀且可維護?
  • [ ] 是否有足夠的測試?
  • [ ] 是否有安全疑慮?
  • [ ] 提交歷史是否乾淨(必要時已壓縮)?

作者:

  • [ ] 請求審查前已完成自我審查
  • [ ] CI 通過(測試、lint、型別檢查)
  • [ ] PR 大小合理(理想小於 500 行)
  • [ ] 與單一功能/修正相關
  • [ ] 描述清楚說明變更內容

衝突解決

識別衝突

# 合併前檢查衝突
git checkout main
git merge feature/user-auth --no-commit --no-ff

# 若有衝突,Git 會顯示:
# CONFLICT (content): Merge conflict in src/auth/login.ts
# Automatic merge failed; fix conflicts and then commit the result.

解決衝突

# 查看衝突檔案
git status

# 檢視檔案中的衝突標記
# <<<<<<< HEAD
# main 的內容
# =======
# 功能分支的內容
# >>>>>>> feature/user-auth

# 選項 1:手動解決
# 編輯檔案,移除標記,保留正確內容

# 選項 2:使用合併工具
git mergetool

# 選項 3:接受其中一方
git checkout --ours src/auth/login.ts    # 保留 main 版本
git checkout --theirs src/auth/login.ts  # 保留功能分支版本

# 解決後,暫存並提交
git add src/auth/login.ts
git commit

衝突預防策略

# 1. 保持功能分支小而短命
# 2. 頻繁 rebase 到 main
git checkout feature/user-auth
git fetch origin
git rebase origin/main

# 3. 與團隊溝通共用檔案的修改
# 4. 使用功能開關取代長生命週期分支
# 5. 及時審查並合併 PR

分支管理

命名慣例

# 功能分支
feature/user-authentication
feature/JIRA-123-payment-integration

# 錯誤修正
fix/login-redirect-loop
fix/456-null-pointer-exception

# 修補(正式環境問題)
hotfix/critical-security-patch
hotfix/database-connection-leak

# 發行
release/1.2.0
release/2024-01-hotfix

# 實驗/POC
experiment/new-caching-strategy
poc/graphql-migration

分支清理

# 刪除已合併的本地分支
git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d

# 刪除已刪除遠端分支的遠端追蹤參照
git fetch -p

# 刪除本地分支
git branch -d feature/user-auth  # 安全刪除(僅已合併)
git branch -D feature/user-auth  # 強制刪除

# 刪除遠端分支
git push origin --delete feature/user-auth

Stash 工作流程

# 儲存進行中的工作
git stash push -m "WIP: user authentication"

# 列出 stash
git stash list

# 套用最近的 stash
git stash pop

# 套用特定 stash
git stash apply stash@{2}

# 刪除 stash
git stash drop stash@{0}

發行管理

語意化版本

MAJOR.MINOR.PATCH

MAJOR:重大變更
MINOR:新功能,向後相容
PATCH:錯誤修正,向後相容

範例:
1.0.0 → 1.0.1(patch:錯誤修正)
1.0.1 → 1.1.0(minor:新功能)
1.1.0 → 2.0.0(major:重大變更)

建立發行版本

# 建立附註標籤
git tag -a v1.2.0 -m "Release v1.2.0

功能:
- 新增使用者認證
- 實作密碼重設

修正:
- 解決登入重新導向問題

重大變更:
- 無"

# 推送標籤至遠端
git push origin v1.2.0

# 列出標籤
git tag -l

# 刪除標籤
git tag -d v1.2.0
git push origin --delete v1.2.0

產生變更日誌

# 從提交產生變更日誌
git log v1.1.0..v1.2.0 --oneline --no-merges

# 或使用 conventional-changelog
npx conventional-changelog -i CHANGELOG.md -s

Git 設定

必要設定

# 使用者身分
git config --global user.name "Your Name"
git config --global user.email "your@email.com"

# 預設分支名稱
git config --global init.defaultBranch main

# Pull 行為(使用 rebase 而非 merge)
git config --global pull.rebase true

# Push 行為(僅推送目前分支)
git config --global push.default current

# 自動修正拼字錯誤
git config --global help.autocorrect 1

# 更好的 diff 演算法
git config --global diff.algorithm histogram

# 彩色輸出
git config --global color.ui auto

實用別名

# 加入 ~/.gitconfig
[alias]
    co = checkout
    br = branch
    ci = commit
    st = status
    unstage = reset HEAD --
    last = log -1 HEAD
    visual = log --oneline --graph --all
    amend = commit --amend --no-edit
    wip = commit -m "WIP"
    undo = reset --soft HEAD~1
    contributors = shortlog -sn

Gitignore 模式

# 相依套件
node_modules/
vendor/

# 建置輸出
dist/
build/
*.o
*.exe

# 環境檔案
.env
.env.local
.env.*.local

# IDE
.idea/
.vscode/
*.swp
*.swo

# 作業系統檔案
.DS_Store
Thumbs.db

# 日誌
*.log
logs/

# 測試涵蓋率
coverage/

# 快取
.cache/
*.tsbuildinfo

常見工作流程

開始新功能

# 1. 更新 main 分支
git checkout main
git pull origin main

# 2. 建立功能分支
git checkout -b feature/user-auth

# 3. 進行變更並提交
git add .
git commit -m "feat(auth): implement OAuth2 login"

# 4. 推送至遠端
git push -u origin feature/user-auth

# 5. 在 GitHub/GitLab 上建立 Pull Request

更新 PR 加入新變更

# 1. 進行額外變更
git add .
git commit -m "feat(auth): add error handling"

# 2. 推送更新
git push origin feature/user-auth

同步 Fork 與上游

# 1. 新增上游遠端(僅一次)
git remote add upstream https://github.com/original/repo.git

# 2. 擷取上游
git fetch upstream

# 3. 將 upstream/main 合併至你的 main
git checkout main
git merge upstream/main

# 4. 推送至你的 fork
git push origin main

還原錯誤

# 還原最後一次提交(保留變更)
git reset --soft HEAD~1

# 還原最後一次提交(捨棄變更)
git reset --hard HEAD~1

# 還原已推送至遠端的最後一次提交
git revert HEAD
git push origin main

# 還原特定檔案的變更
git checkout HEAD -- path/to/file

# 修正最後一次提交的訊息
git commit --amend -m "New message"

# 將遺漏的檔案加入最後一次提交
git add forgotten-file
git commit --amend --no-edit

Git Hooks

Pre-Commit Hook

#!/bin/bash
# .git/hooks/pre-commit

# 執行 lint
npm run lint || exit 1

# 執行測試
npm test || exit 1

# 檢查機密資訊
if git diff --cached | grep -E '(password|api_key|secret)'; then
    echo "偵測到可能的機密資訊,提交已中止。"
    exit 1
fi

Pre-Push Hook

#!/bin/bash
# .git/hooks/pre-push

# 執行完整測試套件
npm run test:all || exit 1

# 檢查 console.log 陳述式
if git diff origin/main | grep -E 'console\.log'; then
    echo "推送前請移除 console.log 陳述式。"
    exit 1
fi

反模式

# 壞:直接提交至 main
git checkout main
git commit -m "fix bug"

# 好:使用功能分支與 PR

# 壞:提交機密資訊
git add .env  # 包含 API 金鑰

# 好:加入 .gitignore,使用環境變數

# 壞:大型 PR(1000 行以上)
# 好:拆分成較小、聚焦的 PR

# 壞:「更新」類提交訊息
git commit -m "update"
git commit -m "fix"

# 好:描述性訊息
git commit -m "fix(auth): resolve redirect loop after login"

# 壞:改寫公開歷史
git push --force origin main

# 好:對公開分支使用 revert
git revert HEAD

# 壞:長生命週期功能分支(數週/數月)
# 好:保持分支短命(數天),頻繁 rebase

# 壞:提交產生的檔案
git add dist/
git add node_modules/

# 好:加入 .gitignore

快速參考

任務 指令
建立分支 git checkout -b feature/name
切換分支 git checkout branch-name
刪除分支 git branch -d branch-name
合併分支 git merge branch-name
Rebase 分支 git rebase main
檢視歷史 git log --oneline --graph
檢視變更 git diff
暫存變更 git add .git add -p
提交 git commit -m "message"
推送 git push origin branch-name
拉取 git pull origin branch-name
Stash git stash push -m "message"
還原最後提交 git reset --soft HEAD~1
還原提交 git revert HEAD