Skip to content

团队协作工作流

本章要点

  • 主流的三种协作模型:GitHub Flow / Git Flow / GitLab Flow
  • 各流程的适用场景与分支结构
  • Pull Request / Merge Request 的完整流程
  • Code Review 的最佳实践
  • 团队 Git 规范建议(提交信息、分支命名、权限)

协作流程的两种基本模型

所有工作流都是下面两种原子操作的组合:

模型做法特点
共享分支(shared branch)所有人直接往同一分支 push简单,但冲突频繁、难以保护
分支 + 合并请求(PR/MR)各自在分支开发,通过 Pull Request 审核后合入有审核关卡,适合中大型团队/开源

现代团队几乎都采用"受保护的主分支 + 功能分支 + PR 审核"的组合。

GitHub Flow(最简单,推荐大多数团队)

只有一条长期分支 main,加上短命的特性分支:

text
main ────────────────────────────────────
        └─ feat/xxx ─ feat/xxx'(PR 合入)
                  └─ fix/yyy ─ fix/yyy'(PR 合入)

流程

text
1. 从 main 拉一条分支:git switch -c feat/xxx
2. 小步提交,及时 push:git push -u origin feat/xxx
3. 发起 Pull Request(PR)
4. 通过 CI 检查 + 至少 1 人 Code Review
5. 合入 main(通常是 squash merge 或 rebase merge)
6. 删除特性分支

适用场景

  • 持续部署(随时可从 main 发布)的互联网团队
  • 中小团队,流程越简单越好
  • 规则:main 始终可发布;分支短命(几小时到几天)

Git Flow(经典但较重)

由 Vincent Driessen 提出,分支职责分明:

text
release 分支: 发布准备(只修 bug,打标签后并入 main 和 develop)

main ────────●(v1.0)────────●(v1.1)──────   ← 只存已发布版本 + 标签
     │        │              │
develop ──────┼──────────────┼──────────────  ← 日常集成主线
     │        │              │
feature/xxx ──┘              │              ← 新功能从 develop 拉出
     │                       │
hotfix/yyy ──────────────────┘              ← 紧急修复从 main 拉出
分支职责从哪来合到哪
main正式发布版本,只接受标签
develop日常开发集成线mainmain(发布时)
feature/*新功能developdevelop
release/*发布准备(稳定、修 bug)developmain + develop
hotfix/*线上紧急修复mainmain + develop

适用场景

  • 需要明确版本管理、计划性发布的团队(如传统软件、游戏、移动端发版)
  • ⚠️ 缺点:分支多、流程重,持续部署团队往往觉得繁琐

GitLab Flow(折中方案)

GitLab 提出的实践,核心思想:

  • 环境分支main(开发)→ pre-production(预发)→ production(生产),代码从左往右流动。
  • 功能分支:从 main 拉出,PR 合回 main
  • 发布分支:按需从 main 拉出维护旧版本。
  • 结合"环境部署"概念:合入特定分支即触发对应环境的部署。

适用:需要多环境(测试/预发/生产)管理的团队,介于 GitHub Flow 与 Git Flow 之间。

Pull Request(PR)全流程实战

第一步:从最新 main 拉分支

bash
$ git switch main
$ git pull                          # 确保基于最新代码
$ git switch -c feat/user-profile   # 命名规范:feat/、fix/、docs/、refactor/

第二步:开发与提交

bash
$ git add -p                        # 分块暂存,保持提交干净
$ git commit -m "feat(user-profile): 增加资料编辑功能"
# 小步提交:一个逻辑 = 一个提交
$ git push -u origin feat/user-profile

第三步:发起 PR

在 GitHub/GitLab 界面操作:

  • 标题:一句话说清"做了什么"(可带前缀,如 feat: xxx
  • 描述:背景、改动内容、测试情况、关联 Issue(Closes #123
  • 目标分支:确认是合并到 main/develop

第四步:等待 CI 与 Review

  • CI(持续集成):提交后自动跑测试/构建,红灯则先修。
  • Code Review:评审人提意见 → 你修改 → 追加提交 → 评审人确认。

第五步:处理评审意见

bash
$ git add . && git commit -m "fix(user-profile): 按评审意见调整表单校验"
$ git push                    # PR 自动更新

💡 评审期间如果 main 有新提交,PR 会显示冲突。解决:

bash
$ git switch main && git pull
$ git switch feat/user-profile
$ git merge main            # 或 git rebase main(取决于团队约定)
$ git push

第六步:合入

常见三种合入方式(团队约定其一):

方式效果适用
Merge commit保留所有提交 + 一个合并提交想完整保留开发历史
Squash and merge所有提交压成一个合入 main特性分支提交较碎时(最常见)
Rebase and merge提交原样线性排列想保持线性且提交本身很整洁

第七步:删除分支

bash
$ git switch main && git pull
$ git branch -d feat/user-profile     # 本地
# 远程分支在 PR 合入后由平台自动删除(或手动删)

Code Review 最佳实践

提交者的责任

  1. PR 尽量:一个 PR 只做一件事,改动量控制在可审范围(几百行以内)。
  2. 提交信息规范,PR 描述写清"为什么"。
  3. 自己先 review 一遍自己的 diff,去掉调试代码、console.log
  4. 及时回应评审意见。

评审者的责任

  1. 关注设计正确性,而不是逐字符挑刺。
  2. 肯定好的写法(让作者有反馈循环)。
  3. 用问题代替命令:"这里为什么不用 X?" 而不是 "改成 X"。
  4. 区分"必须改"(阻塞合入)与"建议"(可后续跟进)。

团队 Git 规范建议模板

text
# 分支命名
feature/功能名       # 新功能
fix/bug简述          # bug 修复
hotfix/紧急修复名    # 线上紧急修复
release/版本号       # 发布准备
docs/说明            # 文档

# 提交信息(约定式提交)
feat(模块): 说明
fix(模块): 说明
refactor(模块): 说明
...

# 规则
1. main/develop 分支受保护:禁止直接 push,必须走 PR
2. PR 必须通过 CI 且至少 1 人 review
3. 提交要小而完整,禁止提交密钥/依赖目录
4. 合入采用 squash merge(或团队约定的一种)
5. 发布用 tag 标记:v主版本.次版本.修订号

受保护分支配置

在 GitHub/GitLab 设置中把 main/develop 设为受保护:

  • 禁止直接 push(只能通过 PR)
  • 要求 PR 前 CI 通过
  • 要求至少 N 个批准
  • 合入后自动删除源分支

开源协作:Fork + PR 模式

text
上游仓库 upstream ──fork──► 你的远程 origin
                              │ clone

                          本地仓库
                              │ push

                          你的远程 origin ──PR──► 上游仓库
bash
$ git clone https://github.com/你的账号/项目.git
$ git remote add upstream https://github.com/原作者/项目.git
$ git fetch upstream
$ git switch -c fix/xxx upstream/main    # 基于上游最新代码开发
# ...提交、推送...
$ git push origin fix/xxx                # 推到自己 fork
# 在平台上从"你的 fork 的分支"发起 PR 到"上游 main"

保持 fork 同步:

bash
$ git fetch upstream
$ git merge upstream/main                # 把上游更新并入自己的 main
$ git push origin main