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 truepull.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 通过
  • 提交历史已整理干净