主题
"后悔药"
git restore
git restore 用于恢复文件到某个状态,常用于撤销工作区或暂存区的修改,是 Git 2.23+ 推荐的撤销命令。
提示
git checkout 也可以用于恢复文件,但功能更为广泛,包括切换分支、恢复文件等。
相比之下,git restore 更加专注于恢复文件状态。
bash
git checkout -- <file>常见命令
bash
# 撤销工作区修改(恢复到暂存区状态)
git restore <file>
# 撤销暂存区修改(恢复到 HEAD,即最后一次 commit)
git restore --staged <file>
# 同时撤销暂存区和工作区的修改
git restore --source=HEAD --staged --worktree <file>
# 恢复到指定 commit 的内容
git restore --source=<commit-hash> <file>批量操作
bash
# 恢复所有文件
git restore .
# 恢复暂存区所有文件
git restore --staged .场景举例
- 编辑了文件但不想保留修改:bash
git restore foo.js - 已 add 到暂存区但想撤回到工作区:bash
git restore --staged foo.js - 恢复文件到某个历史版本:bash
git restore --source=HEAD~2 foo.js
注意事项
git restore只影响本地,不会修改提交历史。- 恢复操作不可逆,谨慎使用。
- 只能撤销未提交的内容,已提交的请用
git reset或git revert。
与 git reset 区别
git restore主要用于撤销文件级别的修改(工作区/暂存区)。git reset主要用于撤销提交和暂存区的内容。
git reset
git reset 用于撤回提交并删除提交记录,有三种常见模式:--soft、--mixed、--hard。
基本语法
bash
# 查看提交历史
git log --oneline
# 重置到指定提交
git reset [模式] <commit-hash>
# 重置到相对位置(HEAD~1 表示上一个提交)
git reset [模式] HEAD~<n>三种模式对比
| 模式 | 暂存区 | 工作区 | 说明 |
|---|---|---|---|
--soft | 保留 | 保留 | 只撤销提交,修改回到暂存区 |
--mixed | 清空 | 保留 | 撤销提交和暂存,修改回到工作区 |
--hard | 清空 | 清空 | 撤销提交并丢弃所有修改 |
谨慎使用 --hard
git reset --hard 会永久丢失所有修改,无法恢复!
基本示例
bash
# 撤销最近一次 commit,保留修改到暂存区
git reset --soft HEAD~1
# 撤销最近一次 commit,修改回到工作区(默认模式)
git reset --mixed HEAD~1
git reset HEAD~1 # 等价写法
# 撤销最近一次 commit,丢弃所有修改
git reset --hard HEAD~1撤销多次提交
bash
# 撤销最近三次 commit
git reset --soft HEAD~3撤销远程提交
如果提交已推送到远程仓库,需要强制推送:
bash
# 本地重置
git reset --hard HEAD~1
# 强制推送到远程
git push -f origin <branch-name>
# 或使用更安全的 --force-with-lease
git push --force-with-lease origin <branch-name>协作注意事项
- 强制推送会影响其他协作者,使用前请确认无其他人基于这些提交工作
--force-with-lease比-f更安全,它会检查远程分支是否有其他人的新提交- 如果推送被拒绝,说明远程有新的提交,此时应该先
git pull或使用git revert代替
git revert
git revert 是更安全的撤销方法,通过创建新提交来撤销之前的更改,不会修改提交历史。
基本用法
bash
# 撤销指定提交
git revert <commit-hash>
# 撤销最近一次提交
git revert HEAD
# 撤销多个提交(从旧到新)
git revert <older-commit>..<newer-commit>处理冲突
bash
# 如果出现冲突,解决后继续
git revert --continue
# 取消 revert 操作
git revert --abort高级选项
bash
# 只生成 revert 内容,不自动提交
git revert --no-commit <commit-hash>
# 撤销合并提交(指定主线分支)
git revert -m 1 <merge-commit-hash>