Git 工作流與 CI/CD 集成實戰 2026 | 團隊協作完全指南

優秀的 Git 工作流和自動化 CI/CD 是團隊高效協作的基石。本文將系統講解主流 Git 工作流、分支策略、代碼審查規範,以及基於 GitHub Actions 的完整 CI/CD 流水線搭建。
一、主流 Git 工作流對比
1.1 Git Flow
main(生產環境)
↑
develop(開發環境)
↑
feature/* release/* hotfix/*特點:
- 嚴格的分支模型,適合版本發佈週期長的項目
- 有明確的
main、develop、feature、release、hotfix分支 - 適合傳統軟件團隊,有明確版本號管理
適用場景: 大型企業項目、桌面軟件、有明確版本週期的產品
操作流程:
# 1. 從 develop 創建功能分支
git checkout develop
git checkout -b feature/user-login
# 2. 開發完成後合併回 develop
git checkout develop
git merge --no-ff feature/user-login
git branch -d feature/user-login
# 3. 發佈版本
git checkout develop
git checkout -b release/1.2.0
# ... 修復 bug ...
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0
git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0
# 4. 緊急修復
git checkout main
git checkout -b hotfix/1.2.1
# ... 修復 ...
git checkout main
git merge --no-ff hotfix/1.2.1
git tag -a v1.2.1
git checkout develop
git merge --no-ff hotfix/1.2.1
git branch -d hotfix/1.2.11.2 GitHub Flow
main
↑
feature/xxx → PR → Code Review → Merge特點:
- 簡單直接,只有
main分支 + 功能分支 - 通過 Pull Request 進行代碼審查
- 適合持續部署,main 分支隨時可發佈
- 是目前最流行的工作流
適用場景: Web 應用、SaaS 產品、持續部署項目
操作流程:
# 1. 從 main 創建分支
git checkout main
git pull origin main
git checkout -b feature/new-dashboard
# 2. 提交代碼
git add .
git commit -m "feat: add new dashboard"
# 3. 推送到遠程
git push origin feature/new-dashboard
# 4. 創建 Pull Request
# 在 GitHub/GitLab 上操作
# 5. Code Review 通過後合併
# 使用 Squash merge 或 Merge commit
# 6. 刪除分支
git checkout main
git pull origin main
git branch -d feature/new-dashboard1.3 Trunk-Based Development
main (trunk)
↑
short-lived feature branches (max 1-2 days)特點:
- 所有人直接向主幹(main)提交
- 功能分支生命週期極短(1-2 天)
- 配合功能開關(Feature Flag)控制發佈
- CI/CD 要求極高,必須有完善的自動化測試
適用場景: 高績效團隊、快速迭代產品、有完善測試體系的團隊
1.4 工作流對比
| 特性 | Git Flow | GitHub Flow | Trunk-Based |
|---|---|---|---|
| 複雜度 | 高 | 中 | 低 |
| 分支數量 | 多 | 中 | 少 |
| 發佈頻率 | 低(按版本) | 中(按 PR) | 高(持續部署) |
| 代碼審查 | 可選 | 核心機制 | 快速審查 |
| 回滾難度 | 低(版本清晰) | 中 | 高 |
| 適合團隊 | 傳統企業團隊 | 大多數團隊 | 高績效團隊 |
| CI 依賴度 | 低 | 中 | 極高 |
二、分支命名規範
2.1 分支命名約定
<類型>/<描述>-<工單ID>常用類型:
| 類型 | 說明 | 示例 |
|---|---|---|
feature/ | 新功能 | feature/user-login-#123 |
fix/ | Bug 修復 | fix/login-error-#456 |
hotfix/ | 緊急修復 | hotfix/payment-bug-#789 |
refactor/ | 代碼重構 | refactor/auth-module |
docs/ | 文檔更新 | docs/api-update |
style/ | 格式調整 | style/format-code |
perf/ | 性能優化 | perf/query-optimization |
chore/ | 構建/工具 | chore/update-deps |
2.2 提交信息規範(Conventional Commits)
<type>(<scope>): <subject>
<body>
<footer>type 類型:
| 類型 | 說明 |
|---|---|
feat | 新功能 |
fix | Bug 修復 |
docs | 文檔變更 |
style | 代碼格式(不影響功能) |
refactor | 重構(非新功能也非修 bug) |
perf | 性能優化 |
test | 測試相關 |
chore | 構建/工具/依賴 |
ci | CI 配置 |
示例:
feat(auth): add OAuth2 login support
- 實現 Google/GitHub OAuth 登錄
- 添加登錄狀態持久化
- 增加登錄失敗錯誤提示
Closes #123fix(api): handle empty response from user endpoint
當用戶未設置頭像時返回空字符串導致前端報錯,
現在返回默認頭像 URL。
Fixes #4562.3 Commitlint 配置
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'feat', 'fix', 'docs', 'style', 'refactor',
'perf', 'test', 'chore', 'ci', 'build', 'revert'
]],
'subject-case': [0],
'subject-max-length': [2, 'always', 72]
}
}// package.json
{
"scripts": {
"prepare": "husky install"
},
"devDependencies": {
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0",
"husky": "^9.0.0"
}
}# 安裝
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'三、代碼審查(Code Review)
3.1 PR/MR 模板
<!-- pull_request_template.md -->
## 變更描述
<!-- 簡要描述本次變更的內容和目的 -->
## 類型
- [ ] feat: 新功能
- [ ] fix: Bug 修復
- [ ] docs: 文檔更新
- [ ] refactor: 代碼重構
- [ ] perf: 性能優化
- [ ] test: 測試補充
- [ ] chore: 構建/工具
## 關聯 Issue
<!-- Closes #123 -->
## 測試
- [ ] 單元測試通過
- [ ] 集成測試通過
- [ ] E2E 測試通過
- [ ] 已在測試環境驗證
## 截圖/錄屏
<!-- 如有 UI 變更,請附上截圖 -->
## 注意事項
<!-- 部署注意事項、數據庫遷移等 -->3.2 代碼審查清單
審查者檢查清單:
3.3 審查禮儀
- 對事不對人:評論代碼,不評論人
- 提供建議而非命令:用「建議」「可以考慮」代替「必須」
- 明確優先級:區分「必須修改」和「可選改進」
- 及時響應:收到審查請求後儘快處理
- 小步提交:PR 不要太大,控制在 400 行以內
四、GitHub Actions CI/CD
4.1 基礎 CI 流水線
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
- name: Type check
run: pnpm typecheck
- name: Test
run: pnpm test -- --coverage
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}4.2 構建並部署到 GitHub Pages
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm build
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- id: deployment
uses: actions/deploy-pages@v44.3 Docker 構建與推送
# .github/workflows/docker.yml
name: Docker Build
on:
push:
tags: ['v*']
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=sha
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max4.4 矩陣測試
# .github/workflows/test-matrix.yml
name: Test Matrix
on: [push, pull_request]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [18, 20, 22]
exclude:
- os: windows-latest
node-version: 18
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- name: Install
run: pnpm install --frozen-lockfile
- name: Test
run: pnpm test4.5 自動發佈 npm 包
# .github/workflows/release.yml
name: Release
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
registry-url: 'https://registry.npmjs.org'
- run: pnpm install --frozen-lockfile
- run: pnpm build
- name: Publish
run: pnpm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true五、高級 CI/CD 配置
5.1 緩存優化
# 依賴緩存
- uses: actions/cache@v4
with:
path: |
~/.pnpm-store
**/node_modules
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
# 構建緩存(Vite)
- uses: actions/cache@v4
with:
path: .vite
key: ${{ runner.os }}-vite-${{ hashFiles('**/vite.config.*') }}
restore-keys: |
${{ runner.os }}-vite-5.2 條件執行
jobs:
test:
runs-on: ubuntu-latest
if: |
github.event_name == 'pull_request' ||
contains(github.event.head_commit.message, '[ci]')
steps:
- uses: actions/checkout@v4
# ...
deploy-staging:
runs-on: ubuntu-latest
needs: [test]
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to Staging
run: echo "Deploying..."5.3 環境變量與 Secrets
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # 環境保護規則
env:
API_URL: ${{ vars.API_URL }}
DB_HOST: ${{ secrets.DB_HOST }}
steps:
- run: echo "$API_URL"5.4 手動觸發
on:
workflow_dispatch:
inputs:
environment:
description: '部署環境'
required: true
default: 'staging'
type: choice
options:
- staging
- production
version:
description: '版本號'
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: |
echo "部署到: ${{ github.event.inputs.environment }}"
echo "版本: ${{ github.event.inputs.version }}"六、Git 高級技巧
6.1 交互式變基
# 合併多個提交
git rebase -i HEAD~5
# 常用操作:
# p, pick = 使用該提交
# s, squash = 合併到前一個提交
# f, fixup = 合併到前一個提交(丟棄提交信息)
# r, reword = 修改提交信息
# e, edit = 編輯該提交
# d, drop = 刪除該提交6.2 Cherry-pick
# 挑選某個提交應用到當前分支
git cherry-pick <commit-hash>
# 挑選多個提交
git cherry-pick <commit1> <commit2>
# 挑選一個範圍
git cherry-pick <start>..<end>6.3 Bisect 二分查找 Bug
# 開始二分查找
git bisect start
# 標記當前版本為壞
git bisect bad
# 標記某個版本為好
git bisect good v1.0.0
# 測試當前版本,標記好/壞
git bisect good # 好版本
git bisect bad # 壞版本
# 找到引入 bug 的提交後,結束
git bisect reset6.4 工作暫存
# 暫存當前工作
git stash push -m "wip: user login"
# 查看暫存列表
git stash list
# 應用最新暫存
git stash pop
# 應用指定暫存
git stash apply stash@{1}
# 刪除暫存
git stash drop stash@{0}
# 清空所有暫存
git stash clear七、團隊協作最佳實踐
7.1 保護主分支
# GitHub 分支保護規則建議
# Settings → Branches → Branch protection rules
Branch name pattern: main
✅ Require a pull request before merging
✅ Require approvals: 1
✅ Require status checks to pass before merging
✅ Require branches to be up to date before merging
Status checks: lint, test, build
✅ Require signed commits
✅ Require linear history
✅ Include administrators7.2 Git 配置建議
# 全局配置
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
# 默認推送當前分支
git config --global push.default current
# 拉取時自動變基(避免無謂的 merge commit)
git config --global pull.rebase true
# 自動設置上游分支
git config --global push.autoSetupRemote true
# 設置默認分支名
git config --global init.defaultBranch main
# 換行符處理
git config --global core.autocrlf input # macOS/Linux
git config --global core.autocrlf true # Windows
# 編輯器
git config --global core.editor "code --wait"7.3 .gitignore 最佳實踐
# Dependencies
node_modules/
.pnp
.pnp.js
# Build output
dist/
build/
.next/
.nuxt/
# Environment files
.env
.env.local
.env.*.local
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Logs
logs/
*.log
npm-debug.log*
# Testing
coverage/
.nyc_output/
# Cache
.cache/
.parcel-cache/
.turbo/八、總結
- ✅ 掌握三種主流 Git 工作流(Git Flow、GitHub Flow、Trunk-Based)
- ✅ 規範的分支命名與 Conventional Commits 提交規範
- ✅ 代碼審查流程與審查清單
- ✅ GitHub Actions 完整 CI/CD 流水線(測試、構建、部署、Docker)
- ✅ 高級 CI/CD 配置(緩存、條件執行、環境變量、手動觸發)
- ✅ Git 高級技巧(變基、cherry-pick、bisect、stash)
- ✅ 團隊協作最佳實踐(分支保護、Git 配置、.gitignore)
優秀的 Git 工作流和 CI/CD 不是一蹴而就的,需要根據團隊規模和項目特點持續迭代優化。
相關閱讀: