引入

“撤销”在 Git 中不是一个动作:可能是撤销工作区修改、取消暂存、反向提交,或者找回已经丢失的提交。执行命令前先确认修改是否已经提交、是否已经推送。

正文

未提交的修改

先确认当前修改位于工作区还是暂存区:

git status
git diff
git diff --staged

丢弃工作区修改,恢复到暂存区版本:

git restore <file>

取消暂存,但保留工作区修改:

git restore --staged <file>

如果文件没有暂存内容,git restore <file> 会恢复到最近一次提交的版本。

这些命令可能造成数据丢失,执行前先用 git diff 检查。

已提交但未推送

修改最近一次提交内容:

git add <file>
git commit --amend

撤销最近一次提交但保留修改:

git reset --soft HEAD~1

如果只是想生成一个反向提交,优先使用:

git revert <commit>

reset --soft 会移动当前分支指针,但保留修改并放在暂存区;如果希望保留修改但取消暂存,可以使用:

git reset --mixed HEAD~1

git reset --hard HEAD~1 会同时丢弃提交和对应的工作区修改,风险较高,使用前应确认不需要这些内容。

已推送的提交

公共分支上不要随意使用 reset 或强制推送改写历史。通常使用 git revert 创建新的撤销提交,更容易让其他开发者同步。

撤销一个已经推送的提交:

git revert <commit>
git push

找回误删的提交

git reflog
git show <commit>
git branch recovery <commit>
git switch recovery

reflog 记录本地引用移动的过程,可用于找回近期切换、重置或变基前的提交。但它不是远程备份,不能替代正常推送和备份。

引出

恢复命令的选择取决于三个问题:修改是否要保留、提交是否已共享、历史是否允许改写。拿不准时先停止继续操作,复制当前目录或创建恢复分支,再处理问题。