第 05 章

团队工作流

分支保护、CODEOWNERS、模板——把好习惯固化成规则

当协作出问题,靠规则而不是靠记忆

团队会踩的坑

PR 流程都懂了,可一旦人多起来,新麻烦就来了

有人直接推 main

约定好了「走 PR」,但总有人忘了,直接 push 到 main。没测试的代码进主干,全组陪葬。

review 找错人

前端改了后端文件没人发现;新人提交没人审。该审的人没审,不该审的人在审。

PR 描述五花八门

有人写一大段,有人只写「修了一下」。issue 报告也格式混乱。信息不齐,每次都要追问。

本章把「好习惯」变成「强制规则」:用分支保护防止误推、用 CODEOWNERS 自动分配 reviewer、用模板统一 PR/issue 格式。
规则写在仓库里,不靠人记,不靠人盯。

开始之前

适合谁

  • 会开 PR,但团队没有规范
  • 想给自己的项目加上专业协作规则
  • 被「谁该 review」「怎么防误推」困扰的组长

你将学会

  • 配置分支保护规则
  • 用 CODEOWNERS 自动指派 reviewer
  • 创建 PR 和 issue 的模板
  • 区分 Git Flow 和 Trunk Based 工作流
  • 遵循 code review 的礼仪和 checklist

本章暂不覆盖

  • Organization 团队管理(企业功能)
  • CI 强制门禁(第 07 章)
  • fork 工作流(第 06 章)

分支保护

给 main 等关键分支上锁——不是谁都能直接推的

图:分支保护如何工作
分支保护的本质:把「应该走 PR」从口头约定变成系统强制。即使有人想直接 push,Git 服务器会拒绝。

免费版能用吗

关键限制:免费账号的分支保护只对公共仓库生效

公共仓库(免费可用)

  • 要求 PR 才能合并
  • 要求 review approve 数量
  • 要求 CI 检查通过
  • 禁止 force push
  • 要求分支保持最新

私有仓库(免费版不支持)

免费账号的私有仓库完全没有分支保护——任何协作者都能直接推 main。

需要分支保护要升级 GitHub Pro(约 $4/月)。

务实建议:学生团队项目用公共仓库,享受全部免费保护规则。涉及敏感代码才用私有,那时要分支保护就得升级 Pro。

配置保护规则

仓库 → Settings → Branches → Add branch protection rule

必开的几项

  • Require a pull request before merging:禁止直接 push
  • Require approvals:至少 N 人 approve(建议 1-2)
  • Require status checks to pass:CI 必须通过(第 07 章)
  • Do not allow bypassing:管理员也别想绕过

选则开

  • Require linear history:强制 fast-forward(配合 Rebase/Squash)
  • Require branches up to date:合并前必须拉最新
  • Restrict who can push:限定可推送的人

配置后,对 main 的直接 push 会被拒绝,必须走 PR 流程。

CODEOWNERS

一个文件,定义「哪些目录归谁审」——自动指派 reviewer

# 文件位置:仓库根目录 CODEOWNERS
# 或 .github/CODEOWNERS

# 全局默认 owner
*                        @组长

# 前端目录由前端组审
/src/frontend/           @alice @bob

# 后端 API 由后端组审
/src/api/                @carol

# 文档任何人都能审
/docs/                   @alice @bob @carol

# 关键配置必须组长审
package.json             @组长
怎么生效:当 PR 改动了 /src/frontend/ 下的文件,GitHub 自动把 alice 和 bob 加为必需 reviewer。不用人记,不用人催。

匹配规则

CODEOWNERS 的路径语法和 .gitignore 类似

写法匹配什么
* 所有文件(全局默认)
/src/ src 目录下所有文件
*.js 所有 js 文件
/docs/* docs 下的直接文件(非递归)
/docs/** docs 下所有文件(递归)
顺序很重要:最后一个匹配的规则生效。所以通用默认(*)要写在最前面,具体规则写在后面来覆盖它。顺序反了会导致「该 A 审的变成了 B 审」。

PR 模板

让每个 PR 自动带上一致的描述骨架

# 文件位置:.github/PULL_REQUEST_TEMPLATE.md

## 改动说明
<!-- 一句话说清做了什么 -->

## 改动类型
- [ ] 新功能
- [ ] bug 修复
- [ ] 重构
- [ ] 文档

## 关联 issue
Closes #

## 如何测试
<!-- 描述验证步骤 -->

## 检查清单
- [ ] 已自测
- [ ] 已更新相关文档
怎么生效:文件放在 .github/PULL_REQUEST_TEMPLATE.md,之后每次开 PR,描述框会自动预填这段内容。作者照着填,格式天然统一。

Issue 模板

给不同类型的 issue 定制表单——bug 报告和功能请求分开

创建方式

仓库 → Settings → Issues → Set up templates。
或手动建:

  • .github/ISSUE_TEMPLATE/bug_report.md
  • .github/ISSUE_TEMPLATE/feature_request.md

效果

新建 issue 时,用户能选择模板。选「bug 报告」会预填:

  • 问题描述
  • 复现步骤
  • 期望/实际行为
  • 环境信息

信息齐全,不用追问。

结构化表单

用 YAML 写的 issue 表单,带输入框和下拉,比纯 markdown 模板更规范

# .github/ISSUE_TEMPLATE/bug.yml
name: Bug 报告
description: 报告一个故障
labels: ["bug"]
body:
  - type: textarea
    id: what-happened
    attributes:
      label: 出了什么问题
      description: 描述你遇到的现象
    validations:
      required: true
  - type: dropdown
    id: browser
    attributes:
      label: 浏览器
      options:
        - Chrome
        - Firefox
        - Safari
表单模式 (.yml) 比 markdown 模板 (.md) 更强:能强制必填、提供下拉选项、校验格式。适合想要规范 issue 质量的团队。文件名以 .yml 结尾放在 ISSUE_TEMPLATE 目录。

工作流派别

团队怎么用分支——主流有两种思路

Git FlowTrunk Based
主干 main + develop 两层 只有 main
分支寿命 长(功能分支活几天到几周) 短(几小时到一两天)
发布 有专门 release 分支 从 main 直接打 tag
适合 有版本发布周期的产品 持续部署的 web 项目

没有谁更好,看你的项目怎么发布。

Git Flow 详解

多分支模型,适合有明确版本节奏的项目

分支角色

  • main:生产环境代码,只合并 release
  • develop:日常集成主线
  • feature/*:功能分支,从 develop 拉出
  • release/*:发布预备
  • hotfix/*:线上紧急修复

典型场景

每两周发一个版本的产品团队。develop 持续集成新功能,临近发版切出 release 分支测试,测试通过合并到 main 发版。

学生项目慎用:对小型项目来说分支太多,反而增加心智负担。

Trunk Based

所有人都往 main 集成,功能分支短命——现代主流

核心做法

  • 只有一个长期分支 main
  • 每个功能开短分支,1-2 天内合并回 main
  • 通过 feature flag 隐藏未完成功能
  • main 随时可部署

为什么流行

  • 分支少,心智简单
  • 集成频繁,冲突小
  • 配合 CI/CD 随时发布
  • Google、Meta 等大厂主流
学生项目推荐 Trunk Based。简单、现代、和持续部署天然契合。一人或小团队项目,就用 main + 短命 feature 分支 + Squash 合并。

review 礼仪

代码审查是技术活,也是人际活

对事不对人

说「这段循环可以简化」,不说「你写得真乱」。
评论代码,不评论人。

解释为什么

「改成 map 更好」不如「改成 map 更易读,因为...」。理由让建议能被理解和接受。

区分必须和建议

必须改的(bug、安全问题)明确说「必须」。可选优化用「建议」「nit:」(小问题)。别把所有意见都当成阻塞。

表扬好的

看到巧妙的实现,留一句「这里写得好」。review 不只是挑错,也认可亮点。

review 清单

审查 PR 时该看什么——一份可复用的 checklist

功能层面

  • 改动是否实现了 PR 描述的目标
  • 有没有遗漏的边界情况
  • 测试覆盖了核心路径吗

代码层面

  • 命名清晰、结构合理
  • 有没有重复代码可抽取
  • 复杂逻辑有没有注释

安全层面

  • 有没有硬编码的密钥、密码
  • 用户输入有没有校验
  • 依赖引入是否可信

工程层面

  • CI 是否通过
  • 有没有破坏性改动
  • 文档/注释是否同步更新

团队反模式

这些做法会让协作变糟,警惕

橡皮图章 review

看都不看直接 approve 凑数。review 数量不等于质量。宁愿慢一点认真审。

巨型 PR

一个 PR 改 50 个文件、3000 行。没人能认真审。拆成小 PR,每个聚焦一件事。

无休止的来回

review 意见反复拉扯几十轮。设立「Nit 不阻塞」原则,小问题别死磕。

动手试一试

把规范装进自己的仓库

你的任务

任务:为自己的项目配置一套基础协作规范。

要求:

  1. 给 main 分支加保护规则:必须走 PR、至少 1 个 approve
  2. 建一个 .github/PULL_REQUEST_TEMPLATE.md
  3. 建一个 .github/ISSUE_TEMPLATE/bug_report.md
  4. 建一个 CODEOWNERS,把自己设为默认 owner
  5. 开一个 PR 验证模板是否生效

提示

  1. 配置文件本身也要通过 PR 合并进仓库
  2. CODEOWNERS 里的用户名是 GitHub 用户名,不是邮箱
第 05 章

小结

你已经能用规则让团队协作更可靠了

本章要点

  • 分支保护:强制走 PR、要求 approve、禁止直接推 main
  • CODEOWNERS:按目录自动指派 reviewer
  • PR/issue 模板:统一描述格式,信息齐全
  • Git Flow(分层)vs Trunk Based(扁平),学生项目推荐后者
  • review 礼仪:对事不对人,区分必须和建议
下一步:第 06 章 开源贡献 —— 把协作能力用到真正的开源世界,学习 fork 模型与 upstream 工作流。