提交前用 git diff –staged 复核暂存区
git commit 提交的是暂存区,不是工作区。但很多人习惯在提交前敲一遍 git diff,看到的却是工作区与暂存区的差异——这两者不是一回事。
什么情况下会撞上这个问题
典型场景是:改了三四个文件,用 git add 挑着加了一部分,然后 git diff 扫一眼觉得没问题就提交。结果提交里混进了本不该带的文件,或者漏掉了某个已经改好却没加进暂存区的文件。
还有一种更隐蔽的情况:git add . 之后又改了几行,git diff 会显示这些新改动,让人误以为它们也在本次提交里,实际上并没有。
为什么会这样
Git 有三个位置:工作区(你正在编辑的文件)、暂存区(下一次提交的内容)、仓库(已提交的历史)。
git diff比较的是工作区和暂存区,也就是“改了但还没 add 的部分”。git diff --staged比较的是暂存区和最后一次提交,也就是“这次 commit 真正会写进去的内容”。
--staged 和 --cached 是同义词,效果完全一样。
所以 git diff 天然看不到你已经 add 进去的东西,而提交恰恰只认暂存区。用错命令,等于检查了错误的对象。
怎么做
第一步,先看状态,确认哪些文件在暂存区:
git status
输出里 “Changes to be committed” 下面列出的,就是这次会提交的文件。绿色表示已暂存,红色表示还在工作区没加。
第二步,复核暂存区的实际内容:
git diff --staged
这条命令逐行显示暂存区相对上次提交的增删。看到不该出现的文件,或者发现某个改动没进来,就回到 git add / git restore --staged 调整。
第三步,如果文件多、只想扫一眼清单,用摘要模式:
git diff --staged --stat
它只列出每个文件改了多少行,适合快速确认“加进来的文件对不对”,不逐行看内容。
第四步,确认无误再提交:
git commit -m "说明这次改了什么"
怎么判断哪一步出了问题
git diff --staged输出为空,但git status显示有改动:说明改动还在工作区,没 add,需要补git add。git diff --staged里出现了不想提交的文件:用git restore --staged <文件>把它撤出暂存区,文件本身不会被删。git diff有内容而git diff --staged没有:改动还没进暂存区,这次提交不会包含它。
边界和代价
git diff --staged 只反映暂存区与 HEAD 的差异,看不到未跟踪的新文件——新建的文件在 git add 之前不会出现在任何 diff 里,得靠 git status 的 “Untracked files” 发现。
另外,如果仓库很大或改动很多,逐行 diff 会很长,这时用 --stat 或 --name-only 先过一遍文件名更实际。二进制文件(图片、压缩包)在 diff 里只显示“Binary files differ”,看不出具体变化,需要单独确认。
养成习惯:提交前先 git status 看清单,再 git diff --staged 看内容。git diff 留给“我还没 add 的改动长什么样”这个用途,两者分工不同。