我见过很多同事,一天工作下来就一条命令:git add .,然后 git commit -m "update"。Git 确实是在用,但等哪天真要回滚、要定位问题、要整理提交记录的时候,就只能干瞪眼。Git 这个工具,“会用”和“精通”之间隔着的不是背命令,而是搞明白每个命令在什么场景下用、用了之后会发生什么、副作用在哪。这篇文章我就挑 12 个我日常工作中真正高频、真正救过命的命令,从提交、急救、整理、排查四个维度拆开讲,每个都带上使用场景、操作示例和踩坑提示。适合所有已经能完成 add/commit/push,但想更进一步把 Git 用顺手的开发者。
1. 提交前把改动捏碎:add -p、amend 和 reset --soft
很多人提交代码的习惯是“攒够了再提交”,一次 commit 里混着三四个逻辑。等代码 review 的时候,别人看不懂你为什么要一起改;等要回滚某个功能的时候,只能把整个提交一起回滚。我自己的经验是:commit 应该小而清晰,一个提交只做一件事。这一章就是围绕这个目标展开的。
1.1 git add -p:不想一次提交全部改动?
场景非常常见:你花了一下午改了一个文件,里面既有“修 bug”的部分,又有“加新功能”的部分,但你想把它们分成两个 commit。这时候 git add . 明显不合适,你需要的是 git add -p。
git add -p 的 -p 是 --patch 的缩写,它会进入交互模式,把文件里的每一块改动(Git 称为 hunk)逐个展示给你,让你决定这一块要不要暂存。交互界面长这样:
bash复制git add -p src/components/Form.js
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? y
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? n
每个选项的含义对应如下:
y:暂存当前这块改动n:跳过当前这块改动q:退出,不再处理后续 hunka:暂存当前文件和后续所有 hunkd:跳过当前文件之后的 hunk,跳到下一个文件s:把当前这块 hunk 拆分成更小的 hunke:手动编辑 hunk(最强大,也最容易出错)?:查看所有选项的帮助
我平常最常用的是 y、n 和 s。如果一个大 hunk 里同时包含了两处不相干的改动,先按 s 拆分,拆完再分别回答 y 和 n,就能做到“一个文件里挑着提交”。
如果你遇到拆分后还是不精确的情况,可以用 e 手动编辑 diff。进入编辑器后,你可以删除某些不想要的行,但要非常小心:每一行的前缀(+、- 或空格)都不能乱动,头部那几行 @@ 是 hunk 定位信息,也必须保留。编辑完保存退出,Git 会按你编辑后的内容暂存。
这里有个很多新手不知道的逻辑:git add -p 不会改变你工作区的文件内容,它只决定“哪些改动进入暂存区”。所以你可以放心用,不会丢代码。提交时一旦一个 commit 里只包含某个逻辑的改动,之后 git log 看历史就会清晰很多,revert 时也能精准撤销。
1.2 git commit --amend:后悔药该不该吃?
提交完了才发现漏了一个文件,或者 commit message 写错了,怎么办?不用重新 commit,直接 git commit --amend。
--amend 的意思是“修订上一次提交”,用法很灵活:
bash复制git commit --amend # 修改上次提交的提交信息
git commit --amend --no-edit # 不修改提交信息,只补充文件改动
git commit --amend -m "新的提交信息" # 直接指定新信息,不进入编辑器
比如我经常遇到的情况:
bash复制git add src/api/user.js src/utils/validator.js
git commit -m "feat: 增加用户注册校验"
# 突然发现漏了一个文件
git add src/api/auth.js
git commit --amend --no-edit
这样第二次提交不会产生新的提交记录,而是把 auth.js 直接塞进了上一次 commit 里。从外面的视角看,这个分支上只有一条提交,干净利落。
但这里有个非常关键的点,也是我见过很多人踩坑的地方:--amend 不是“修改”,而是“替换”。Git 会生成一个全新的 commit 对象,虽然它在 log 里的位置没变,但 commit hash 已经不同了。如果你 amend 的是一个已经 push 到共享分支的提交,那相当于重写了历史,其他同事 pull 的时候会得到一堆分叉,得靠 git pull --rebase 去解,严重的时候还会把别人的提交搞乱。
所以我的底线是:只要这个 commit 已经 push 到了公共分支,就绝不动它。只在本地还没推送、或者推送到自己个人 feature 分支时使用 --amend。
1.3 git reset --soft:撤销 commit 但保留工作区
git reset 大概是 Git 里最让人头大的命令之一,因为它有 --soft、--mixed、--hard 三种模式。先记住一个结论:日常整理提交,--soft 最安全。
三种模式的区别可以用一张表看清楚:
| 参数 | HEAD指针 | 暂存区 | 工作区 | 典型场景 |
|---|---|---|---|---|
--soft |
移动 | 保留 | 保留 | 想重新组织提交,但不想丢任何改动 |
--mixed(默认) |
移动 | 重置 | 保留 | 想撤销 add,让改动回到工作区 |
--hard |
移动 | 重置 | 清空 | 彻底丢掉某次提交及其改动 |
具体到 --soft,它的核心价值在于“后悔了想重新来”。比如你连续
