Git 暂存改动:3 种方式一次讲清,附选择建议与失败排查

编程狮(w3cschool.cn) 2026-10-04 07:06:07 浏览数 (26)
反馈

Git 暂存改动:3 种方式一次讲清

你改完几个文件,准备提交时却犹豫:到底该一次性 git add . 还是逐个加?漏改了怎么办,加错了又怎么撤回?Git 暂存改动有三种常用方式:用 git add 按文件或按目录加入暂存区、用交互式 git add -p 只挑部分修改、以及用 git restore --staged 把误加的内容撤出暂存区。选错方式主要带来"提交里混进无关改动"或"该提交的没提交"两类问题。本文基于 Git 2.x 验证,从最小示例讲到分区边界与失败排查。今天这篇文章,编程狮就把这块讲透。

先看结论

你的意图 命令 作用
加入整个文件/目录 git add 文件 该文件全部改动进入暂存区
只挑部分改动 git add -p 逐块选择要暂存的片段
撤出暂存区 git restore --staged 文件 保留工作区修改,仅退出暂存

一句话:全加用 add,精细挑选用 add -p,加错了用 restore --staged 撤回;暂存区只是"待提交清单",不决定最终文件内容。

一、工作区、暂存区与提交的关系

理解 Git 暂存改动,先要分清三个区域:工作区是你正在编辑的目录,暂存区是下一次提交的内容清单,仓库里才是真正落定的历史。提交时 Git 只把暂存区里的改动打包。先用 Git 教程 里的图示建立这个心智模型,后面命令才好理解。

# 查看三个区域的状态差异
git status
git diff        # 工作区 vs 暂存区
git diff --cached  # 暂存区 vs 上一次提交

运行 git status 后,预期结果会把文件分别列在"已暂存"和"未暂存"两组;git diff --cached 显示本次将提交的内容。若你发现某文件同时出现在两组,说明它部分改动已暂存、部分没有,这是最常见的混淆来源。检查这一步能避免把半成品一起提交。

二、方式一:git add 按文件或目录加入

最直观的 Git 暂存改动写法是 git add,后面跟文件路径或目录。它把目标里所有改动整体加入暂存区,适合改动清晰、想一次性提交的场景。

# 只加某个文件
git add src/app.js
# 加整个目录下的改动
git add src/

运行后 git status 会把这些文件移到"已暂存"区,预期结果是它们变成绿色待提交状态。失败排查上,若提示 pathspec 'x' did not match,说明路径写错或在错误目录执行,用 git status 核对真实文件名即可修复。注意 git add . 会递归加入当前目录下一切改动,容易把调试日志、密钥文件一起提交,敏感项目务必指定具体路径。常用路径规则可查 Git 速查手册 快速对照。路径还支持更精细的写法:git add 'src/**/*.ts' 用通配符批量匹配同类文件,路径修饰符 :(exclude) 可反向排除某些文件;若想看 add 之后到底会纳入哪些改动,先 git add -n 文件 做"空跑"预览最稳妥。养成"先预览、再暂存"的习惯,能避免把 .env、日志这类敏感文件误提交进仓库,也方便在大型重构里精确控制提交范围。

Git 工作区暂存区提交三区结构图

三、方式二:git add -p 只挑部分改动

当你在一个文件里既修了 bug 又加了实验代码,却只想提交前者时,用 git add -p 进入交互式挑选。它会把文件改动拆成"块(hunk)",让你逐个决定暂存与否。配合 Git Magic 教程 的练习能更快上手。

# 对每个文件的改动逐块确认
git add -p
# 只针对某个文件做部分暂存
git add -p src/app.js

运行后终端逐个展示代码块,预期结果中你输入 y 暂存、n 跳过、s 进一步拆分。验证时再次 git diff --cached 确认只有目标片段进入暂存区。边界上,二进制文件无法分块,只能整体暂存;若某块选错,退出后用 git restore --staged 撤出再重来即可,不会丢失工作区内容。交互里还有几个好用的子命令:s 把当前块再拆细、e 进入编辑器手工修改要暂存的片段、? 随时查看全部选项、q 直接退出。当你需要比块更细的粒度时,可改用 git add -i 进入完整交互菜单,在其中单独编辑补丁(patch)模式。配合 git diff --cached 反复核对,你能做到"一次提交只含一个逻辑改动",这正是高质量提交记录的基石。

四、方式三:git restore --staged 撤回误加

加错文件时,不要慌着删改。用 git restore --staged 可以把改动从暂存区撤出,工作区里的修改原样保留,后续可重新挑选。这是对 git add 的"后悔药"。

# 仅撤出暂存区,不动工作区文件
git restore --staged src/app.js
# Git 2.23 之前用旧语法
git reset HEAD src/app.js

运行后 git status 预期结果显示该文件回到"未暂存"区,但文件内容不变。版本边界上,git restore 是 2.23 引入的新命令,老版本用 git reset HEAD 等价替代。easygit 教程 也演示了这类日常管理操作。git restore 还能双向控制范围:git restore --source=HEAD~1 --staged --worktree 文件 可同时把暂存区和工作区都恢复到上一版;只加 --staged 则只动暂存区、保留磁盘改动。注意它与 git checkout -- 文件 的区别:后者直接丢弃工作区改动且无撤销余地,误操作风险更高,日常回退建议优先用 git restore --staged。三种方式对比见下表:

方式 粒度 适用 注意
git add 路径 文件/目录整体 改动干净、整批提交 避免 add . 误带敏感文件
git add -p 代码块 同一文件内混合改动 二进制不能分块
git restore --staged 撤出暂存 加错后的回退 不删工作区内容

失败排查清单:加不进去做 git status 看是否在仓库内;撤回无效确认是否用了新命令与版本匹配;提交后发现漏改则补 git add 再 git commit --amend。

Git 暂存改动三种方式适用场景对照图

总结

Git 暂存改动有三种常用方式:add 整体加、add -p 挑片段、restore --staged 撤出。

  • 改动干净时用 git add 路径,提交前用 git status 确认范围;
  • 同一文件混合改动用 git add -p 只挑需要的块;
  • 加错了用 git restore --staged 撤回,工作区内容不受损。

下一步想系统学 Git,可以先过一遍 Git 教程,再结合速查手册巩固命令。

延伸学习

想把这块知识系统补齐,可以按这个顺序来:

  1. 想跟着课程动手练,Git 快速入门体验课程 是边学边写的形式;
  2. 看版本控制的整体入门,Git 版本控制入门笔记 从第一步讲起,适合延伸阅读;
  3. 需要更完整的命令参考,Git 书中文版教程 适合随时查阅。

常见问题

Q:git add . 和 git add -A 有区别吗?

A:在仓库根目录执行时两者几乎等价,都会加入所有改动(含删除)。区别在于子目录下 git add . 只处理当前目录,而 git add -A 覆盖整个仓库。日常建议明确写文件路径,避免误带文件。

Q:restore --staged 会删掉我的修改吗?

A:不会。它只把文件从暂存区移回工作区,磁盘上的内容保持不变,你只是"取消暂存",之后还能重新 add。

Q:add -p 里把某块选错了怎么办?

A:直接退出交互,用 git restore --staged 文件 把整文件撤出暂存区,再重新 git add -p 挑选即可,工作区改动不会丢。

0 人点赞