Appearance
撤销暂存区
概述
暂存区(Staging Area)是 Git 的重要概念,文件在被提交前需要先添加到暂存区。本节将介绍如何撤销暂存区的修改。
理解暂存区
Git 的三个区域
工作区 (Working Directory) 暂存区 (Staging Area) 本地仓库 (Repository)
│ │ │
│ git add │ git commit │
│ ──────────────────────> │ ────────────────────> │
│ │ │
│ git restore │ git reset │
│ <────────────────────── │ <──────────────────── │
│ (--staged) │ (--soft) │查看暂存区状态
bash
# 查看状态
git status
# Changes to be committed:
# modified: file.txt
# 查看暂存区内容
git diff --cached
git diff --staged
# 查看暂存区文件列表
git diff --cached --name-onlygit restore --staged
git restore --staged 是撤销暂存区的推荐命令。
基本用法
bash
# 撤销指定文件的暂存
git restore --staged file.txt
# 撤销多个文件的暂存
git restore --staged file1.txt file2.txt
# 撤销当前目录下所有暂存的文件
git restore --staged .
# 撤销所有暂存的文件
git restore --staged :/撤销部分暂存
bash
# 交互式选择要撤销暂存的内容
git restore --staged -p file.txt
# 或使用 --patch
git restore --staged --patch file.txt同时撤销暂存和工作区
bash
# 同时撤销暂存区和工作区的修改
git restore --staged --worktree file.txt
# 或简写为
git restore -SW file.txt
# 同时撤销所有文件
git restore -SW .git reset HEAD
git reset HEAD 是传统的撤销暂存方式。
基本用法
bash
# 撤销指定文件的暂存
git reset HEAD file.txt
# 撤销多个文件的暂存
git reset HEAD file1.txt file2.txt
# 撤销所有暂存的文件
git reset HEAD
# 或简写为
git resetreset 的默认模式
bash
# git reset 默认使用 --mixed 模式
# 等同于
git reset --mixed HEAD
# 效果:
# 1. 暂存区被重置到 HEAD
# 2. 工作区保持不变
# 3. 文件从暂存区移回工作区查看撤销效果
bash
# 撤销前
git status
# Changes to be committed:
# modified: file.txt
# 执行撤销
git reset HEAD file.txt
# 撤销后
git status
# Changes not staged for commit:
# modified: file.txt部分撤销暂存
交互式撤销
bash
# 交互式选择要撤销暂存的部分
git reset -p
# 或使用 add 的反向操作
git add -p file.txt # 添加部分到暂存区
# 然后使用 reset 撤销不需要的部分使用 git add 覆盖
bash
# 如果只想保留文件的部分修改在暂存区
# 1. 先撤销整个文件的暂存
git restore --staged file.txt
# 2. 重新添加需要的部分
git add -p file.txt使用补丁方式
bash
# 创建补丁
git diff --cached > staged-changes.patch
# 撤销暂存
git restore --staged .
# 选择性应用补丁
git apply -p staged-changes.patch撤销场景示例
场景 1:撤销误添加的文件
bash
# 误添加了文件到暂存区
git add wrong-file.txt
# 撤销暂存
git restore --staged wrong-file.txt
# 或
git reset HEAD wrong-file.txt场景 2:撤销部分文件的暂存
bash
# 添加了多个文件,但只想提交部分
git add .
git status
# Changes to be committed:
# new file: src/main.js
# new file: src/utils.js
# new file: test.js
# 不想提交 test.js
git restore --staged test.js
# 现在只有 src/ 下的文件在暂存区
git status
# Changes to be committed:
# new file: src/main.js
# new file: src/utils.js
# Untracked files:
# test.js场景 3:修改已暂存的文件
bash
# 文件已暂存
git add file.txt
# 又修改了文件
# 此时暂存区和工作区不一致
# 查看差异
git diff file.txt # 工作区 vs 暂存区
git diff --cached # 暂存区 vs HEAD
# 选择 1:撤销暂存,保留工作区修改
git restore --staged file.txt
# 选择 2:用工作区版本覆盖暂存区
git add file.txt
# 选择 3:用暂存区版本覆盖工作区
git restore file.txt场景 4:撤销所有暂存
bash
# 暂存了多个文件
git add .
# 撤销所有暂存
git restore --staged .
# 或
git reset HEAD场景 5:重新组织提交
bash
# 暂存了多个不相关的修改
git add .
git status
# Changes to be committed:
# modified: feature-a.js
# modified: feature-b.js
# modified: bugfix.js
# 想要分开提交
# 1. 撤销所有暂存
git restore --staged .
# 2. 分别添加和提交
git add feature-a.js
git commit -m "Add feature A"
git add feature-b.js
git commit -m "Add feature B"
git add bugfix.js
git commit -m "Fix bug"暂存区操作对比
bash
# 添加到暂存区
git add file.txt
# 撤销暂存(保留工作区修改)
git restore --staged file.txt # 新命令
git reset HEAD file.txt # 旧命令
# 撤销暂存和工作区修改
git restore --staged --worktree file.txt # 新命令
git checkout HEAD -- file.txt # 旧命令
git reset --hard HEAD -- file.txt # 不支持文件参数查看暂存区详情
查看暂存区内容
bash
# 查看暂存区与 HEAD 的差异
git diff --cached
git diff --staged
# 查看暂存区与工作区的差异
git diff
# 查看暂存区文件列表
git ls-files --stage
# 查看暂存区文件内容
git show :file.txt查看暂存区统计
bash
# 查看暂存区文件统计
git diff --cached --stat
# 查看暂存区文件数量
git diff --cached --numstat | wc -l常见问题
撤销暂存后文件消失
bash
# 如果文件是新添加的(未跟踪)
git add new-file.txt
git restore --staged new-file.txt
# 文件回到未跟踪状态,不是消失
git status
# Untracked files:
# new-file.txt撤销暂存后想恢复
bash
# 撤销暂存后,工作区仍有修改
# 如果想恢复暂存,重新 add 即可
git add file.txt部分撤销失败
bash
# 如果文件有冲突标记
# 需要先解决冲突
git status
# Unmerged paths:
# both modified: file.txt
# 解决冲突后
git add file.txt总结
git restore --staged是撤销暂存的推荐命令git reset HEAD是传统的撤销方式- 撤销暂存不会影响工作区修改
- 可以交互式选择要撤销的部分
- 合理组织暂存区有助于创建清晰的提交
下一步
学习完撤销暂存区后,建议继续学习:
