Skip to content
Git
工作流与最佳实践

工作流与最佳实践

Git 是工具,工作流是方法。好的工作流 + 好的习惯 = 高效的团队协作。


主流工作流

Git Flow(经典分支模型)

main    ─●────────────●──────────────●──→
          \          / \            /
release    ●──●──●──●   \          /
                          \        /
develop  ──●──●──●──●──●──●──●──●──●──→
              \    / \    /
feature     ●──●──●   ●──●──●
分支 用途 来自 合并到
main 生产代码 — —
develop 开发主线 main main
feature/* 新功能 develop develop
release/* 发布准备 develop main + develop
hotfix/* 紧急修复 main main + develop

适合:有固定发布周期的传统软件项目。缺点:分支多,流程重。

GitHub Flow(简洁版)

main ─●────●────●────●────●──→
        \    /    /    /
feature   ●──●    /    /
                  /    /
           ●──●──●    /
                      /
               ●──●──●

原则:

  1. main 始终可部署
  2. 所有工作从 main 创建描述性分支
  3. 随时推送到远程分支
  4. 通过 Pull Request 合并
  5. 合并后立即部署

适合:持续部署的 Web 应用、SaaS 项目。GitHub、Netflix 等广泛使用。

Trunk-Based Development(主干开发)

main ─●──●──●──●──●──●──●──→ (每天多次合并)
       │   │  │   │
       └───┘  └───┘  (短生命周期分支,< 1 天)

原则:

  • 只有一条长期分支(trunk/main)
  • 分支生命周期极短(几小时到一天)
  • 通过 Feature Flag 控制未完成功能
  • 高频小批量合并

适合:成熟的 DevOps 团队,有完善的 CI/CD 和测试体系。Google、Facebook 都用此模型。

工作流选择

工作流 分支数 合并频率 团队规模 发布节奏
Git Flow 多 低 大团队 固定周期
GitHub Flow 少 中 中小团队 随时部署
Trunk-Based 极少 极高 成熟团队 持续部署

Commit 规范

Conventional Commits(约定式提交)

<type>(<scope>): <description>

[optional body]

[optional footer]

type 类型:

Type 说明
feat 新功能
fix 修复 bug
docs 文档变更
style 代码格式(不影响功能)
refactor 重构(非新功能、非修复)
perf 性能优化
test 添加/修改测试
chore 杂务(构建、依赖等)
ci CI/CD 变更
build 构建系统变更
# 示例
feat(auth): add JWT authentication
fix(api): handle null response in user endpoint
refactor(db): simplify connection pool logic
docs(readme): update installation instructions
chore(deps): bump lodash to 4.17.21

# 破坏性变更(BREAKING CHANGE)
feat(api)!: drop support for v1 endpoints
# 或
feat(api): migrate to v2 API

BREAKING CHANGE: v1 API endpoints are no longer available.

💡 使用 Conventional Commits 可以自动生成 CHANGELOG 和语义化版本号。配合 commitlint 工具可做提交信息校验。

提交信息的七个规则

  1. 标题与正文之间空一行
  2. 标题不超过 50 字符
  3. 标题首字母大写(中文不限)
  4. 标题不用句号结尾
  5. 标题用祈使语气(“fix” 而不是 “fixed”)
  6. 正文每行不超过 72 字符
  7. 正文解释 做了什么 和 为什么,而不是"怎么做"
# ✅ 好的提交信息
fix: prevent racing of requests

Introduce a request id and a reference to the latest request. Dismiss
incoming responses other than the latest one.

Remove timeouts which were previously used to mitigate the racing issue
but are now unnecessary.

Closes #123

# ❌ 不好的提交信息
fixed bug
updated code
wip
各种修改

分支命名规范

<type>/<description>

feature/login-with-oauth
fix/null-pointer-in-parser
hotfix/critical-security-patch
chore/update-dependencies
refactor/user-service
docs/api-guide

日常操作最佳实践

提交前

  • git status 确认状态
  • git diff --staged 检查暂存区内容
  • 不要 git add . 一把梭,先用 git status 看一眼
  • 大改动考虑 git add -p 分批提交

分支操作

# ✅ 创建 feature 分支前先同步 main
git checkout main
git pull --rebase
git checkout -b feature/new-work

# ✅ 定期从 main 同步(用 rebase 保持线性历史)
git fetch origin
git rebase origin/main

# ✅ 推送前整理提交
git rebase -i HEAD~3     # squash 细碎的修复提交
git push --force-with-lease  # 仅在个人分支

# ❌ 不要在 main 上直接开发
# ❌ 不要 force push main/master

合并时

# ✅ 合并 feature 到 main 时,用 --no-ff 保留分支痕迹
git checkout main
git merge --no-ff feature

# ✅ 或者先 rebase 再 merge(保持线性)
git checkout feature
git rebase main
git checkout main
git merge feature

安全实践

敏感信息处理

# ❌ 绝不要将密码、密钥、token 提交到 Git

# 如果已经提交了:
# 1. 立即轮换泄露的密钥/密码
# 2. 用 git filter-repo 清除历史(不只是 reset)
git filter-repo --path secrets/config.yml --invert-paths --force
git push origin --force --all
# 3. 通知团队成员重新 clone

# ✅ 使用环境变量或外部密钥管理
# .env 文件应加到 .gitignore

.gitignore 安全项

# 永远忽略
.env
.env.*
*.pem
*.key
secrets/
credentials/
*.p12

签名验证

# 配置 GPG 签名
git config --global user.signingkey <GPG-KEY-ID>
git config --global commit.gpgsign true

# 签名 commit
git commit -S -m "Signed commit"

# 签名 tag
git tag -s v1.0 -m "Signed release"

# GitHub/GitLab 会显示 Verified 标记

提交历史维护

好的历史长什么样

git log --oneline
# a1b2c3d Add login rate limiting
# d4e5f6g Fix OAuth token refresh bug (#234)
# g7h8i9j Refactor auth middleware
# j0k1l2m Add JWT authentication
# m3n4o5p Initial project setup

坏的提交历史

# wip
# fix test
# fixed
# update
# 修改了bug
# 再次修复
# oops
# tmp

💡 原则:每个 commit 应该是一个逻辑上完整的、可单独 review 的最小变更。未来的你(和同事)通过 git log 来理解项目历史。


常见陷阱汇总

🚨 陷阱 说明 ✅ 正确做法
Force push 到共享分支 覆盖团队成员的提交 仅 force push 个人分支,且用 --force-with-lease
rebase 已推送的提交 改写他人已基于的 commit hash 只 rebase 本地未推送的提交
git add . 无脑用 可能混入调试代码、临时文件 先 git status,必要时 git add -p
commit 信息无意义 “fix”、“update"没实际信息 遵循 Conventional Commits 规范
提交大文件 仓库膨胀,clone 变慢 使用 Git LFS 或 .gitignore
在 main 上开发 没有分支隔离 总是在 feature 分支上工作
忘记 .gitignore 构建产物、依赖被提交 项目创建时就建立 .gitignore
提交敏感信息 密钥泄露到仓库历史 .env 加入 .gitignore,泄露后立即轮换密钥
pull 产生无意义 merge commit 本地和远程分叉时自动 merge 配置 pull.rebase true 或 pull.ff only
长时间不推送 本地 commit 堆积,冲突风险大 每天 push,小批量提交

日常操作 Checklist

每天开始

  • git fetch --prune 更新远程分支信息
  • 在正确的分支上开发(不在 main)

开发中

  • 小的、有意义的 commit
  • 提交信息遵循规范
  • 定期 git stash 或 commit WIP

准备推送

  • git status 确认变更都是想要的
  • git diff --staged 检查暂存内容
  • git rebase -i 整理提交历史(可选)
  • git pull --rebase 同步远程

合并前

  • 代码已经过 Review
  • CI 通过
  • 提交历史已整理干净