git add 后文件未进暂存区,需检查三件事:编辑器是否未真正写入磁盘、当前目录和路径是否正确、是否被 .gitignore 忽略;-a 同步所有变更,-u 仅处理已跟踪文件的修改与删除,--intent-to-add 标记新文件但不暂存内容。

git add 后文件没进暂存区?检查这三件事
不是 git add 失效,而是它只响应「工作区当前状态」——如果文件刚被编辑完但编辑器没真正写入磁盘(比如 VS Code 启用“延迟保存”),或者你 cd 错了目录、路径写成了相对上层路径,git add 就会静默跳过。
- 用
git status --short确认文件是否显示为??(未跟踪)或M(已修改);只有这些状态的文件才可能被add到暂存区 - 路径必须相对于当前工作目录,
git add ./src/index.js和git add src/index.js等价,但git add /home/user/project/src/index.js会报错fatal: pathspec '...' did not match any files - 忽略规则优先级高于
add:如果.gitignore里写了node_modules/,哪怕手动git add node_modules/foo.js也会被拒绝,提示The following paths are ignored by one of your .gitignore files
git add -A、-u、--intent-to-add 分别干啥
这三个参数控制「哪些变更类型」进入暂存区,不是“全加”“只加修改”的简单区别,而是和 Git 的内部索引状态强绑定。
-
git add -A:同步所有变更——新增、修改、删除都暂存。等价于git add .(Git 2.0+),但注意它不会递归进入未git init的子目录 -
git add -u:只暂存「已被 Git 跟踪过」的文件的修改和删除,对新文件(??)完全无视。适合改完一堆旧文件又不想误提新配置文件时用 -
git add --intent-to-add(简写-N):把新文件标记为“准备跟踪”,但不暂存内容。之后git status会显示为A(新文件),再编辑一次再add才真正暂存内容。适合先建空文件占位,等逻辑写完再一起提交
为什么 git add *.js 有时不生效
Shell 展开和 Git 解析路径的顺序容易出问题,尤其在 Windows CMD 或某些 zsh 配置下。
- 如果当前目录没有
.js文件,Bash 会原样传*.js给 Git,而 Git 默认不支持通配符匹配(除非加--显式分隔),结果就是报错error: pathspec '*.js' did not match any files - 安全写法是加引号:
git add "*.js",让 Git 自己遍历工作区匹配;或者先用ls *.js确认有结果再执行 - 注意
**/*.js这种写法在 Git 2.22+ 才原生支持,老版本需启用globstar或改用git add $(find . -name "*.js")(慎用,含空格路径会崩)
暂存区内容不对?别急着 commit,先看 index
暂存区(index)是独立快照,和工作区、HEAD 不实时同步。你以为 add 了,其实可能只是覆盖了上次的暂存状态,没包含最新编辑。
- 用
git ls-files --stage查看暂存区真实哈希值,对比git hash-object <file></file>看是否一致,能快速定位“明明改了却没暂存”的问题 - 误
add了敏感内容?立刻git restore --staged <file></file>(Git 2.23+)或git reset HEAD <file></file>(旧版),不要等commit再后悔 - 部分暂存(如
git add -p)后,同一文件可能同时存在暂存版和工作区版,git diff显示未暂存差异,git diff --staged显示已暂存差异——这个双视图是常态,不是 bug
最常被忽略的是:Git 暂存区不记录文件权限变更(除非 core.filemode=false),也不自动处理换行符(core.autocrlf 设置不当会导致 add 后 diff 乱跳)。这些底层行为不报错,但会让协作时的 add 结果和预期不一致。











