在旧版本的Git中,我们通常使用git checkout或git reset来撤销或恢复文件。然而,这两个命令功能过于强大且语义混淆(checkout既可以切换分支,又可以撤销文件修改)。为了解决这个问题,Git在2.23版本引入了两个新的、语义更清晰的命令:git switch用于切换分支,而git restore则专注于撤销文件修改。
git restore是处理工作目录和暂存区错误的“瑞士军刀”,它安全且直观,是恢复误改文件的最佳实践。
1. git restore 简介
git restore的核心功能是把文件恢复到历史版本(通常是HEAD,即最近一次提交)或者暂存区(Staging Area)的状态。
它主要处理两种场景:
1. 撤销工作目录 (Working Directory) 的修改。
2. 将文件从暂存区 (Staging Area) 中移除(Unstage)。
2. 准备工作:初始化演示环境
我们首先创建一个新的Git仓库并进行一次初始提交,以便进行演示。
mkdir git_restore_demo
cd git_restore_demo
git init
# 创建并提交初始文件
echo "This is the initial content of file_a." > file_a.txt
git add file_a.txt
git commit -m "Initial commit: Add file_a"
3. 场景一:恢复工作区中尚未暂存的修改
如果你在工作目录中修改了一个文件,但还没有执行git add将其放入暂存区,并且你意识到这些修改是错误的,想要彻底丢弃,将其恢复到上次提交的状态。
步骤与操作
- 制造修改:
echo "This line is an accidental modification." >> file_a.txt
cat file_a.txt
# 输出:
# This is the initial content of file_a.
# This line is an accidental modification.
git status
# 状态:Changes not staged for commit
- 使用 **git restore 恢复:**
如果不指定任何选项,git restore默认是从HEAD(最近一次提交)中恢复文件,覆盖工作区的修改。
git restore file_a.txt
# 查看恢复后的内容
cat file_a.txt
# 输出:
# This is the initial content of file_a.
git status
# 状态:Nothing to commit, working tree clean
总结: git restore
4. 场景二:将文件从暂存区中移除 (Unstage)
如果你错误地使用git add将文件添加到了暂存区,但你又不希望将这个版本纳入到下一次提交中,你需要将它“撤出”暂存区。
步骤与操作
- 制造修改并暂存:
echo "Content ready to be committed." > file_b.txt
git add file_b.txt
git status
# 状态:Changes to be committed
- 使用 **git restore –staged 移除暂存:**
我们需要告诉Git,我们想要恢复的是暂存区的状态,而不是工作区。通过添加–staged选项,Git会从HEAD中恢复暂存区,但保留工作区的修改。
git restore --staged file_b.txt
# 此时文件内容不变,但文件状态改变
cat file_b.txt
# 输出:Content ready to be committed.
git status
# 状态:
# No changes added to commit (use "git add" and/or "git restore <file>" to update what will be committed)
# Changes not staged for commit:
# (modified: file_b.txt)
总结: git restore –staged
5. 场景三:同时恢复工作区和暂存区的修改
如果你已经修改了文件,并且将其暂存了(git add),但现在你决定彻底放弃所有这些修改。
步骤与操作
- 制造修改并暂存: (沿用上面的 file_b.txt,它现在在工作区有修改。)
git add file_b.txt
# 确认 file_b.txt 再次进入暂存区
git status
# 状态:Changes to be committed (file_b.txt)
- 执行两次恢复操作:
首先,使用 –staged 清空暂存区,然后使用默认命令清空工作区。
# 1. 恢复暂存区 (Unstage)
git restore --staged file_b.txt
# 2. 恢复工作区 (Discard working changes)
git restore file_b.txt
# 查看最终状态
git status
# 状态:Nothing to commit, working tree clean
# 文件内容也回到了HEAD的状态(即被删除或初始状态)
注意: 如果文件在初始提交中不存在,并且你在工作区创建后又撤销,git restore会直接删除工作区中的该文件。
git restore 参数速查表
| 命令 | 目标区域 | 效果 | 用途 | 备注 |
|---|---|---|---|---|
| git restore |
工作区 | 将文件恢复到暂存区或HEAD状态 | 丢弃未暂存的修改 | 最常用 |
| git restore –source HEAD |
工作区 | 等同于上一个命令 | 明确指定从HEAD恢复 | |
| git restore –staged |
暂存区 | 将文件从暂存区移回工作区 | 撤销 git add 操作 | 保留工作区修改 |
| git restore –source |
工作区 | 将文件恢复到指定提交的状态 | 从历史版本中恢复文件 |
汤不热吧