Git 完全指南 / 18 - 最佳实践:分支策略、Commit 规范、Monorepo、团队协作
第十八章:最佳实践
掌握 Git 命令只是起点,建立高效的团队协作流程才是真正的目标。
18.1 分支策略
18.1.1 GitHub Flow
最简单的工作流,适合持续部署的小型团队。
main ─────────────────────────────────────────►
│ │ │
└─feature1┘ PR + Review ─┘ merge
│
└─feature2──┘ PR + Review ──┘ merge
规则:
main分支始终可部署- 所有新功能从
main创建分支 - 通过 PR 合并回
main - 合并后立即部署
# GitHub Flow 工作流
$ git switch -c feature/login main
$ # 开发...
$ git push -u origin feature/login
$ gh pr create --title "feat: add login"
$ # 审查通过后合并
$ gh pr merge --squash
$ # 删除远程分支
$ git push origin --delete feature/login
18.1.2 Git Flow
经典的分支模型,适合有明确发布周期的项目。
main ────────●──────────────────●─────────────────►
│ ↑
│ merge + tag
│ │
release ─────┼──────────────────●─────────────────►
│ ↑
│ merge
│ │
develop ─────●────●────●────●───●────●────●──────►
↑ ↑ ↑ ↑ ↑
feature1 feature2 feature3
| 分支 | 用途 | 生命周期 |
|---|---|---|
main | 生产代码 | 永久 |
develop | 开发主线 | 永久 |
feature/* | 新功能 | 临时 |
release/* | 发布准备 | 临时 |
hotfix/* | 生产紧急修复 | 临时 |
# Git Flow 示例
# 创建功能分支
$ git switch -c feature/payment develop
$ # 开发...
$ git switch develop
$ git merge --no-ff feature/payment
# 创建发布分支
$ git switch -c release/1.2.0 develop
$ # 测试和修复...
$ git switch main
$ git merge --no-ff release/1.2.0
$ git tag -a v1.2.0 -m "Release v1.2.0"
$ git switch develop
$ git merge --no-ff release/1.2.0
# 热修复
$ git switch -c hotfix/1.2.1 main
$ # 修复...
$ git switch main
$ git merge --no-ff hotfix/1.2.1
$ git tag -a v1.2.1 -m "Hotfix v1.2.1"
$ git switch develop
$ git merge --no-ff hotfix/1.2.1
18.1.3 Trunk-Based Development
所有开发者在主干(trunk/main)上工作,适合 CI/CD 成熟的团队。
main ───●───●───●───●───●───●───●───●───●───●──►
↑ ↑ ↑ ↑
short-lived branches (< 1 day)
规则:
- 分支存活时间 < 1 天
- 频繁集成到主干
- 使用 Feature Flag 控制未完成功能
- 需要强大的 CI/CD 和测试覆盖
18.1.4 分支策略对比
| 策略 | 复杂度 | 发布频率 | 团队规模 | CI/CD 要求 |
|---|---|---|---|---|
| GitHub Flow | 低 | 持续 | 小型 | 中 |
| Git Flow | 高 | 周期性 | 中大型 | 低 |
| Trunk-Based | 中 | 持续 | 任何 | 高 |
18.2 Commit 规范
18.2.1 Conventional Commits
# 格式
<type>(<scope>): <description>
[optional body]
[optional footer(s)]
| 类型 | 说明 | 示例 |
|---|---|---|
feat | 新功能 | feat(auth): add OAuth2 login |
fix | Bug 修复 | fix(api): handle null response |
docs | 文档 | docs(readme): update setup guide |
style | 格式 | style: fix indentation |
refactor | 重构 | refactor(db): optimize queries |
perf | 性能 | perf(render): lazy load images |
test | 测试 | test(auth): add unit tests |
build | 构建 | build(webpack): update config |
ci | CI/CD | ci(github): add deploy workflow |
chore | 杂项 | chore(deps): update dependencies |
revert | 回滚 | revert: feat(auth): add OAuth2 |
18.2.2 提交信息最佳实践
# ✅ 好的提交信息
feat(auth): implement JWT token refresh
- Add automatic token refresh before API calls
- Implement retry logic for 401 responses
- Store refresh token in httpOnly cookie
Closes #123
# ❌ 不好的提交信息
fix
update code
WIP
asdfghjkl
18.2.3 Commitlint 配置
# 安装
$ npm install --save-dev @commitlint/cli @commitlint/config-conventional
# commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
'feat', 'fix', 'docs', 'style', 'refactor',
'perf', 'test', 'build', 'ci', 'chore', 'revert'
]],
'subject-max-length': [2, 'always', 72],
'body-max-line-length': [2, 'always', 100],
}
};
18.3 Monorepo 最佳实践
18.3.1 目录结构
monorepo/
├── apps/
│ ├── web/ # 前端应用
│ ├── api/ # 后端 API
│ └── admin/ # 管理后台
├── packages/
│ ├── shared/ # 共享代码
│ ├── ui/ # UI 组件库
│ └── config/ # 共享配置
├── tools/
│ └── scripts/ # 构建脚本
├── package.json # 根配置
├── turbo.json # Turborepo 配置
└── pnpm-workspace.yaml
18.3.2 变更检测
# 只在变更的包上运行 CI
# 使用 Turborepo
$ turbo run test --filter=...[origin/main]
# 使用 Lerna
$ lerna run test --since origin/main
# 使用 pnpm
$ pnpm --filter=...[origin/main] test
18.3.3 Monorepo 工具对比
| 工具 | 特点 | 适用场景 |
|---|---|---|
| Turborepo | 高性能构建缓存 | JavaScript/TypeScript |
| Nx | 智能依赖分析 | 多语言 Monorepo |
| Lerna | npm 包管理 | npm 库发布 |
| Bazel | 大规模构建 | 超大型项目 |
| Rush | 微软出品 | 企业级 JS Monorepo |
18.4 团队协作规范
18.4.1 CODEOWNERS 文件
# .github/CODEOWNERS 或 docs/CODEOWNERS
# 默认审查者
* @team-leads
# 前端代码
/apps/web/** @frontend-team
# 后端代码
/apps/api/** @backend-team
# 数据库迁移
/apps/api/migrations @dba-team
# CI/CD 配置
/.github/** @devops-team
/.gitlab-ci.yml @devops-team
# 文档
/docs/** @tech-writers
*.md @tech-writers
18.4.2 Pull Request 规范
| 检查项 | 配置方式 | 说明 |
|---|---|---|
| 最少审查人数 | Branch Protection | 至少 1-2 人批准 |
| CI 必须通过 | Branch Protection | 所有检查绿色 |
| 禁止 force push | Branch Protection | 保护历史 |
| 线性历史 | Merge Queue | 避免混乱的合并图 |
| 代码所有者审查 | CODEOWNERS | 关键代码需指定人审查 |
| 关联 Issue | PR 模板 | 要求填写 Issue 编号 |
18.4.3 代码审查清单
## 审查清单
### 功能性
- [ ] 代码实现了需求描述的功能
- [ ] 边界条件已处理
- [ ] 错误处理完善
### 代码质量
- [ ] 代码可读性良好
- [ ] 命名清晰准确
- [ ] 无重复代码
- [ ] 遵循项目代码规范
### 安全性
- [ ] 无硬编码密钥/密码
- [ ] 输入已验证
- [ ] SQL 注入/XSS 防护
### 测试
- [ ] 有单元测试
- [ ] 测试覆盖关键逻辑
- [ ] 测试用例清晰
18.5 .gitignore 最佳实践
# 项目根目录的 .gitignore
# 依赖
node_modules/
vendor/
.pnp.*
# 构建产物
dist/
build/
*.o
*.so
# 环境配置
.env
.env.local
.env.*.local
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# 日志
*.log
logs/
# 测试/覆盖率
coverage/
.nyc_output/
18.6 仓库管理清单
新项目初始化
# 1. 创建仓库
$ mkdir project && cd project
$ git init -b main
# 2. 创建 .gitignore
$ curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
# 3. 创建 README
$ echo "# Project Name" > README.md
# 4. 设置分支保护(在平台上操作)
# 5. 创建 CODEOWNERS
$ mkdir -p .github
$ cat > .github/CODEOWNERS << 'EOF'
* @team-leads
EOF
# 6. 配置 CI/CD
$ mkdir -p .github/workflows
# 创建 ci.yml...
# 7. 首次提交
$ git add -A
$ git commit -m "chore: initial project setup"
# 8. 添加远程并推送
$ git remote add origin git@github.com:org/project.git
$ git push -u origin main
业务场景
| 场景 | 推荐实践 |
|---|---|
| 初创团队快速迭代 | GitHub Flow + Conventional Commits |
| 企业有固定发布周期 | Git Flow + Semantic Versioning |
| 高频持续部署 | Trunk-Based + Feature Flags |
| 前后端分离项目 | Monorepo (Turborepo) + 统一 CI |
| 微服务架构 | 每服务独立仓库 + 共享库 (npm/Go module) |
| 开源项目维护 | GitHub Flow + CODEOWNERS + 严格 Review |
扩展阅读
- Conventional Commits
- Semantic Versioning
- GitHub Flow
- Trunk-Based Development
- Turborepo
- A successful Git branching model
- Google Engineering Practices