搜「git 撤销提交命令」的人,多数已经执行过 commit,但没想清楚要撤到哪一层:只撤提交、连暂存一起撤,还是把工作区改动也一起丢掉;以及这条提交究竟有没有推到远端。动手前先跑 git status 和 git log --oneline -5,把工作区、暂存区、本地提交、远端分支这四层状态看清楚,再决定用 git reset 还是 git revert。这两条命令的差别不在语法,而在「这条提交有没有别人已经拿到」。
撤销提交先分清两件事:提交是否已推送到共享分支,改动是否需要保留。只有自己用、还没推送的提交,用git reset --soft HEAD~1撤回提交并保留改动,改完重新git commit;已经推送或被他人拉取的分支,用git revert <sha>追加一条反向提交,不改写历史。动手前留一份git log --oneline和git status的输出,撤完用git log、git diff核对。不确定时不要用--hard,它会连工作区改动一起丢掉。
撤销提交命令:先把能核对的事实摆清楚
先把四层对象的当前状态打出来,不要凭印象判断:工作区有没有未提交改动、暂存区有没有已 add 的内容、本地分支最新提交是哪一条、远端分支相对本地是领先还是落后。
git status
git log --oneline -5 --decorate
git branch -vv
git reflog -5
git status:输出里会明确写出当前在哪个分支、有哪些改动已暂存(Changes to be committed)、哪些还没暂存(Changes not staged)、有没有未跟踪文件。git log --oneline -5 --decorate:看最近 5 条提交的短哈希和提交信息,--decorate会标出 HEAD、本地分支和远端跟踪分支指向哪里。git branch -vv:每行末尾方括号里是上游分支,以及 ahead/behind 数字。ahead 大于 0 说明有本地提交还没推送。git reflog -5:本地的 HEAD 移动记录,reset、commit、rebase 都会留痕,误操作后通常靠它找回原提交。reflog 的保留时长受gc.reflogExpire影响,具体数值用git help config在你本机确认,不同版本和配置可能不同。
还需要确认一个外界条件:这个分支是不是多人共用。可以看仓库页面上该分支的合并请求/拉取请求列表,或者直接问同事;命令侧可以用 git branch -r --contains <提交哈希> 看远端分支是否已经包含目标提交。这一步不做,后面的选择就没有依据。
撤销提交命令最容易搞错的一点
最常见的误解是把「撤销提交」等同于「删掉这次改动」。实际上 git reset 只移动分支指针,配合不同参数才决定改动留在哪里:--soft 保留暂存区,--mixed(默认)把改动退回工作区,--hard 直接丢弃工作区和暂存区的内容。很多人照着记忆敲 git reset --hard HEAD~1,提交是没了,改的代码也没了。
真正要分清的分界是:这条提交有没有离开你的机器。判断动作很具体——

git log --oneline @{u}..HEAD
这条命令列出「上游分支还没有、只有本地有」的提交。如果目标提交出现在列表里,说明它只在本地,可以用 reset 改写;如果列表为空或没有目标提交,说明它已经推送到远端,此时应改用 revert。没有配置上游分支时 @{u} 会报错,可以换成显式的 git log --oneline origin/main..HEAD,分支名按实际替换。
撤销提交命令:一个照着就能做完的做法
场景一,提交还没推送、只有自己用。目标是保留改动、只取消这次 commit:
# 1. 确认状态
git log --oneline -3
git status
# 2. 撤回最近一次提交,改动回到暂存区
git reset --soft HEAD~1
# 3. 确认:应看到 HEAD 指向上一条提交,改动仍在 Changes to be committed
git status
# 4. 改完重新提交
git commit -m "重新整理后的提交信息"
第 2 步之后如果 git status 里改动出现在「Changes to be committed」,说明改动完整保留;如果什么都不剩,说明参数用错了,立刻用 git reflog 找到原提交哈希,git reset --soft <哈希> 退回。要连暂存区一起退,把 --soft 换成 --mixed;只有确认改动可以丢弃时才用 --hard。

场景二,提交已经推送,或者分支有别人在提交。不要改写历史,改为追加一条反向提交:
# 1. 找到要撤的提交哈希
git log --oneline -5
# 2. 生成反向提交,--no-edit 使用默认提交信息
git revert --no-edit <提交哈希>
# 3. 确认无误后推送
git push
第 2 步正常会直接成功并新建一条提交。如果提示冲突,说明这次改动和后面的提交有重叠,需要手工解决冲突文件后再执行 git revert --continue;想放弃这次 revert,用 git revert --abort 回到操作前。
撤销提交命令:怎么验证结果对不对
验证不靠感觉,靠命令输出和页面显示对照。
git log --oneline -5:正常结果是目标提交从历史里消失(reset 场景),或者多出一条Revert "..."的新提交(revert 场景),哈希和顺序都符合预期。git status:正常结果应显示工作区干净,或者只剩下你预期保留的改动。若出现大量意料之外的删除,先别继续操作。git diff HEAD:reset 之后如果要确认改动是否还在,这条命令应能看到尚未提交的差异内容;如果输出为空,说明改动已经不在工作区。git branch -vv:推送之后,方括号里的 ahead 数字应回到 0(或在 revert 后推送完成时归零),说明本地和上游一致。- 仓库页面:打开该分支的提交列表或合并请求页面,确认最新提交标题、提交数与本地一致。页面位置各平台不同,通常在分支详情的 Commits 标签页。
验证通过再继续后续提交。如果验证发现对不上,用 git reflog 找到操作前的哈希退回,这比继续在错误状态上叠提交要安全得多。