commit · diff
git:20260817.d4dfa41 to git:20261014.9c3854a
2 added, 2 removed. Audit A to A.
---
name: commit
description: 要把改动提交成 git commit 时用。先看清工作区里有几件事、按主题分组、只暂存这一组,以及消息里该写什么不该写什么。
---
# 提交改动
## 先看清全貌,再决定分几个提交
并行跑这三条,不要只看 `git status`:
```bash
git status --short
git diff --stat
git log --oneline -10
```
`git log` 那条是为了**照着这个仓库的习惯来**:标题用什么语言、有没有
`feat:` 这类前缀、正文写多细、提交粒度是大批次还是一改一提。不同仓库
差别很大,猜错的表现是这个提交在历史里读起来像外来的。
判据是**能不能用一句话说清这批改动解决了什么问题**。能,就是一个提交;
需要用「以及」连接两件无关的事,就该切开。
## 只暂存这一组
`[约束]` **不要 `git add -A` 或 `git add .`**,除非你已经确认工作区里只有
这一件事。工作区经常同时挂着几个主题的改动(有些还是用户自己没提完的),
全加进去就把无关的东西一起提了,而那之后再拆得动历史。
逐个文件或逐个目录加,然后确认一遍暂存区:
```bash
git add path/to/a path/to/b
git status --short # 前缀 M/A 的那些就是这次要提的
```
## 别带上不该带的
- 密钥与凭证:`.env`、`*.pem`、`auth.json`、任何含 token 的文件。
- 用户明确要求提交这类文件时,先提醒他一次。
+ 用户明确要求提交这类文件时,先提醒用户一次。
- 但**生成物不一定该跳过**。有些仓库把生成的类型、schema、lockfile
检入版本库并在 CI 里校验同步 —— 那种情况下漏掉它们会让 CI 直接红。
不确定就看 `.gitignore` 和 CI 配置,别按直觉判断。
## 消息
标题一行说清这批做了什么,语言和格式跟着 `git log` 里的既有风格。
正文写**为什么**,不是罗列做了什么 —— 做了什么看 diff 就有,而
「为什么这么做、为什么不用另一条路」只有现在写下来。特别值得写的:
- 不选另一条方案的理由;
- 踩过的坑和它的**具体症状**(「表现是按了没反应」比「修复了事件问题」
有用得多);
- 这次改动依赖或守住了什么约束,破了会怎样。
用 HEREDOC 传消息,保证换行不被吃掉:
```bash
git commit -m "$(cat <<'EOF'
标题
正文段落。
EOF
)"
```
## 提交之后
跑一次 `git status` 确认干净,并把结果告诉用户 —— 包括**没提交的那些还留在
- 工作区**,那是他接着要处理的。
+ 工作区**,那是用户接着要处理的。
## 不要做的事
- 不要 `git push`、切分支、`stash`、`reset --hard`,除非用户明确要求。
- 不要 `--amend`,除非用户明确要求、那个提交是本次对话里刚做的、而且还没推。
- 提交被 pre-commit hook 拒了:修问题再提一个**新的**提交,不要 amend。
- 没有改动就不要造一个空提交。