Skip to content

团队里怎么把 Git 用顺:协作约定

个人会用 Git,只能说明你能把代码提交上去。团队把 Git 用顺,靠的是约定一致。

很多 Git 问题表面上看像命令问题,实际上是协作规则没对齐。比如有人默认 pull --rebase,有人默认 merge;有人会改公开历史,有人完全不接受;有人习惯把一个需求拆成多个小提交,有人喜欢一次推一大坨。只要这些习惯不统一,历史就会越来越难看,冲突也会越来越难处理。

这一页不追求“标准答案”,而是记录一套我更认可、也更容易落地的团队约定。

先说目标

一套靠谱的 Git 协作约定,至少应该满足这几件事:

  • 新人加入后,不需要猜每个人的习惯
  • 出冲突时,大家知道先看什么、按什么顺序处理
  • 需要回滚时,能尽量少动公开历史
  • 回头排查问题时,提交历史还能看

约定 1:主干保持可发布,功能开发走分支

最基础的一条:

  • mainmaster 只保留相对稳定、可发布的代码
  • 新需求、新重构、新实验都在功能分支上做

不要直接在主干上长期开发。短期看省事,长期看一定会把发布和回滚搞得很被动。

约定 2:分支名尽量见名知意

我更建议按类型区分:

  • feature/login-form
  • fix/user-cache
  • hotfix/payment-timeout
  • refactor/request-layer

这样做的好处很直接:

  • 远程分支列表更容易扫
  • PR 标题和分支名更容易对应
  • 排查历史时不需要猜 ashu-test-3 到底是什么

约定 3:开工前先同步主干,再切分支

shell
git switch main
git pull --ff-only
git switch -c feature/login-form

如果这条约定能稳定执行,后面很多“为什么我这里冲突这么多”的问题,压根不会出现。

约定 4:提交要小,而且每个 commit 只表达一件事

比起“提交要勤”,我更在意“提交要干净”。

好的 commit 通常满足:

  • 改动范围相对集中
  • 提交说明能说清楚为什么改
  • 回滚时不会牵连一堆无关修改

反过来,下面这种提交就很容易埋雷:

  • 一个 commit 里混了需求开发、重构、样式调整、日志清理
  • 提交说明只有 fixupdate调整
  • 一次性堆了几百个文件,自己都说不清重点

约定 5:公开历史尽量不改,真的要改就明确范围

我自己的建议很明确:

  • 本地个人分支,可以 rebase
  • 已经推到远程、但只有你自己在用的分支,可以谨慎 rebase
  • 多人共享分支,尽量不要重写历史

如果确实需要强推,优先:

shell
git push --force-with-lease

不要直接裸 --force

--force-with-lease 不是绝对安全,但至少能挡住一部分“我以为没人动,结果别人刚好推了新提交”的事故。

约定 6:团队先统一 pull 策略

这个点经常被忽略,但实际上非常影响历史长相。

至少要提前说清楚两件事:

  • 日常 pull 默认是 merge,还是 rebase
  • 主干分支是否允许本地出现额外 merge commit

如果团队偏线性历史,可以统一:

shell
git pull --rebase

如果团队更重视保留真实合流关系,也可以统一走 merge。但最糟糕的情况是每个人都按自己的习惯来。

约定 7:合并前先做最起码的自检

我觉得至少要看三件事:

shell
git status
git log --oneline --decorate -10
git diff origin/main...HEAD

这不是形式主义,而是避免把下面这些东西一起带进主干:

  • 临时调试代码
  • 本地没整理过的碎提交
  • 和当前需求无关的顺手修改

约定 8:冲突先处理现场,再处理情绪

发生冲突时,先做三件事:

  1. 看清楚是同步主干时冲突,还是合并分支时冲突
  2. 确认当前分支和目标分支分别是谁
  3. 再决定是继续解决,还是直接中止

不要一冲突就开始机械地“保留当前 / 保留传入”。你至少得知道这两边各自代表谁。

约定 9:线上问题优先走可追踪的回滚路径

如果代码已经推到远程并被别人使用,优先考虑:

  • revert 撤销
  • tag 标记已发布版本
  • 修复完成后再补回开发分支

不要在紧急情况下顺手改写公共历史。线上越着急,越该选可追踪的做法。

一套我更认可的最小工作流

可以粗暴概括成下面这样:

  1. 从最新主干切功能分支
  2. 小步提交,必要时用 add -p
  3. 开发过程中用 rebasemerge 同步主干,按团队约定执行
  4. 合并前整理自己的提交历史
  5. 发起 PR 或合并请求
  6. 合并后删除旧分支

这套流程不花哨,但足够覆盖大多数日常开发。

常见坑

  • 大家都“差不多会用 Git”,但没有统一约定,最后每个人历史都长得不一样
  • 把“我本地能跑”当成“已经可以合并”
  • 团队不约定 pull 策略,时间久了 merge commit 和 rebase 历史混在一起
  • 习惯性强推远程分支,最后没人敢相信历史

最后一句

团队协作里最有价值的不是某一条命令,而是“哪些动作默认可以做,哪些动作必须先打招呼”。

这个边界一旦清楚,Git 会顺很多。