Best Practices

小步提交与主题分支整洁度

把提交粒度和主题分支边界同时管住,review 会更快,rebase 更稳,回滚也会轻松很多。

适合谁看
  • 希望把 Git 用得更稳的个人或团队
  • 准备建立协作规范的维护者
前置知识
  • 至少有一次真实协作经验
  • 知道常见命令但还没形成稳定习惯
常见风险
  • 把建议当硬规则而忽略上下文
  • 只记流程,不理解背后的协作边界

为什么"提交小一点"不是形式主义

聚焦提交与主题分支每个提交聚焦单一意图,每个主题分支聚焦单一功能。提交是微观的原子,分支是宏观的主题。
短生命周期分支 (< 2 天)
ABCD
主题分支: main
定期 rebase 同步主线
ABCM
BEF
提交前:git diff --staged 确认
ABCE'F'
主题分支: feature

很多人觉得提交拆细是"高级技巧",

  • reviewer 更容易理解每一步为什么存在
  • 你自己更容易在 rebase 时整理历史
  • 出问题时可以更精准地回滚或 cherry-pick

如果提交过大、分支过脏,Git 还是能工作,但团队协作会明显变慢。

1. 一个提交只表达一个完整动作

更理想的提交通常像这样:

  • 新增登录审计日志
  • 修复导航遮挡问题
  • 调整发布脚本里的版本号解析

不太理想的提交通常像这样:

  • 登录日志 + 导航样式 + 文档顺手更新
  • 一天所有工作都塞进一个提交
  • “先这样提交,后面再看”

你不需要追求极端细碎,但应该追求“每个提交都有单一主题”。

2. 分支里只保留和当前主题相关的提交

主题分支最怕的不是提交多,而是夹杂无关噪声:

  • 临时 debug 代码
  • 顺手改掉的无关格式问题
  • 和当前需求无关的文件整理

这些噪声会让 reviewer 不知道哪些是你真正希望讨论的改动。
更糟的是,后面如果要回滚或 cherry-pick,就会把无关东西一起带走。

3. 用 add -p 和分次提交维护边界

如果你在一个文件里同时改了两类事情,可以用更细的方式分开:

git add -p
git commit -m "refactor: simplify branch status summary"
git add -p
git commit -m "fix: stop detached-head hint from flashing"

这种做法虽然多一步,但会大幅提升历史可读性。

4. 用例:为什么小步提交能明显改善 review

假设一个 PR 里有 12 个文件改动。
如果它被拆成 4 个清楚的提交,reviewer 更容易:

  • 先看结构调整
  • 再看行为修复
  • 最后看测试和文档

而不是面对一团“看起来都对,但不知道顺序和重点”的大 diff。

5. 用例:为什么 rebase 时更容易整理

当分支里每个提交都很单一时,交互式 rebase 的判断会简单很多:

  • 哪几个应该 squash
  • 哪个提交标题需要重写
  • 哪个提交应该提前
  • 哪个试错提交应该直接删掉

如果提交本身已经混合了三四种事情,你几乎不可能在 rebase 阶段轻松补救。

6. 用例:为什么回滚边界会更清楚

线上出了问题时,你最希望做到的是:

  • 精准定位是哪一组提交引入了问题
  • 能单独 revert 掉这组改动

如果一个提交里混入了多个主题,revert 就会变成“修掉一个问题,同时误伤另外两个功能”。

7. 送审前值得做的整洁度检查

在发起 review 前,至少看一遍:

git log --oneline --decorate -10
git diff --stat origin/main...
git diff --name-only origin/main...

重点检查:

  • 提交标题是否表达动作
  • 有没有明显噪声提交
  • 有没有和主题无关的文件混进来

8. 特殊情况:不是所有试错都要保留到最终分支

本地开发时有试错很正常,但不是所有试错都值得进入最终送审历史。

通常更好的做法是:

  • 本地允许试错提交存在
  • 送审前再整理成可读历史

这样既不打断开发,也不会把整个探索过程强行丢给 reviewer。

9. 一套可执行的最低标准

  1. 一个提交只讲一件事
  2. 一个分支只承载一个主题
  3. 无关改动不要顺手带进去
  4. 送审前必须自己读一遍 logdiff
  5. 如果你自己都解释不清提交顺序,reviewer 也很难看懂

建议连着看

  • 原子提交与提交叙事
  • 主题分支策略
  • 提交评审前准备专题