Git reset 与 revert 的区别:如何安全撤销错误提交

举报
GGBondHere 发表于 2026/11/01 08:06:02 2026/11/01
【摘要】 介绍 Git reset 和 revert 的区别,讲解 soft、mixed、hard 三种重置模式,以及本地提交、远程共享提交的安全撤销方法和注意事项。

前言

使用 Git 开发项目时,偶尔会遇到提交完成后才发现代码有问题的情况。比如提交了错误配置、漏改了文件,或者某次功能修改需要回滚。

Git 提供了 reset 和 revert 两种常见的撤销方式。它们看起来都能撤销提交,但对提交历史的处理方式完全不同。

简单来说,reset 可以移动当前分支的位置,而 revert 会通过新的提交撤销之前的修改。实际使用时,最重要的是区分代码是否已经推送到远程仓库。

一、先查看提交历史

在执行撤销操作前,建议先查看最近几次提交:

git log --oneline -5

假设输出如下:

c3d4e5f 修复登录接口
b2c3d4e 更新用户配置
a1b2c3d 初始化项目

每条记录前面的是提交哈希,可以用来指定需要撤销的提交。

如果只是想撤销最新一次提交,也可以直接使用 HEAD。

HEAD 通常指向当前检出的提交,HEAD~1 则表示沿第一父提交向前移动一次。

二、git reset 的三种常用模式

reset 最容易混淆的是 soft、mixed 和 hard。它们的区别主要体现在是否保留暂存区和工作区的修改。

1. --soft:撤销提交,保留暂存内容

git reset --soft HEAD~1

执行后,当前分支会回到上一个提交,但暂存区和工作区保持原样。

也就是说,原来最新提交中的修改通常仍然处于已暂存状态,可以直接重新提交。

适合刚提交完才发现提交说明写错,或者想把几个提交重新整理的情况。

2. --mixed:撤销提交,保留文件修改

git reset --mixed HEAD~1

mixed 是 reset 的默认模式,因此也可以直接写成:

git reset HEAD~1

执行后,当前分支回到上一个提交,暂存区会重置,但工作区中的文件修改仍然保留。

适合想重新选择需要提交的文件或修改部分代码的场景。

3. --hard:同时重置暂存区和工作区

git reset --hard HEAD~1

这个操作比较危险。

它会把当前分支、暂存区和受影响的工作区文件都恢复到指定提交的状态。未提交的已跟踪文件修改可能直接丢失,部分妨碍写入的未跟踪文件也可能被删除。

因此,不建议在有重要未提交修改时随意执行。

如果只是提交信息写错,或者想重新整理提交,通常没有必要使用 hard。

三、git revert:通过新提交撤销修改

如果错误提交已经推送到远程仓库,并且可能被其他人拉取,更适合使用 revert。

例如:

git revert HEAD

Git 会根据指定提交产生反向修改,并在正常完成时创建一个新的提交。

假设原来的历史是:

A --- B --- C

如果撤销 C,历史会变为:

A --- B --- C --- D

其中 D 是用于撤销 C 的新提交。

这样既能取消之前的代码修改,又能保留完整的历史记录,其他开发者也能看到这次回滚操作。

如果需要撤销更早的某个普通提交,也可以指定它的哈希:

git revert c3d4e5f

不过需要注意,如果后续提交修改过相同的代码,revert 可能发生冲突。它并不能保证任何历史提交都能无冲突地撤销。

四、reset 和 revert 怎么选?

可以按照下面的原则理解:

对比项 git reset git revert
是否移动当前分支 是 通常不会回退分支
是否保留被撤销的提交记录 提交可能不再位于当前分支历史中 保留
是否生成新提交 通常不生成 正常完成时生成
已经推送到共享分支 不建议随意回退 通常更合适
本地整理未推送的提交 比较方便 一般没必要

这里还有一个细节:reset 并不一定意味着提交对象立刻被 Git 删除。旧提交可能仍然能够通过 reflog 等方式找到,但不应该把这种恢复机制当作可靠备份。

五、实际例子:刚提交就发现漏了文件

假设刚执行:

git commit -m "更新配置"

随后发现还有一个配置文件忘记加入。

如果提交还没有推送,可以直接补充文件,然后修改最后一次提交:

git add config.yaml
git commit --amend --no-edit

这通常比先 reset 再重新提交更加方便。

如果希望重新整理全部修改,也可以使用:

git reset --soft HEAD~1

然后补充文件并重新提交。

需要注意,amend 也会改写提交历史,所以对于已经推送到多人共享分支的提交,同样需要谨慎。

六、撤销已经推送的错误提交

假设一次错误修改已经推送到了远程 main 分支,而且其他开发者可能已经拉取。

这时不要直接 reset 后强制推送覆盖远程历史。

可以先确认工作区没有未处理的修改:

git status

然后撤销指定的普通提交:

git revert <提交哈希>

确认新提交内容正确后,再按正常流程推送。

如果 revert 过程中发生冲突,可以先解决冲突,再使用:

git revert --continue

如果决定放弃本次撤销操作,可以使用:

git revert --abort

对于合并提交,revert 还涉及主线父提交的选择,操作比普通提交更复杂,不建议直接套用上述命令。

七、操作前的几个建议

第一,执行 reset 前先检查 git status,确认有没有需要保留的工作区修改。

第二,已经推送到共享分支的提交,优先考虑 revert,避免无意中改写其他人的提交历史。

第三,--hard 并不是更彻底、更推荐的撤销方式。它只适合明确需要丢弃相关修改的场景。

第四,如果只是想取消某个文件的暂存,不需要移动分支,可以使用:

git restore --staged config.yaml

根据实际目的选择命令,比记住一堆 reset 参数更加重要。

总结

Git reset 和 revert 都能用于撤销修改,但它们适用的场景不同。

如果是本地尚未推送的提交,reset 可以方便地调整分支历史,并根据 soft、mixed、hard 决定保留哪些修改。

如果提交已经进入共享分支,revert 通常更加稳妥,因为它通过新提交撤销修改,不需要覆盖原来的提交历史。

日常开发中,建议遵循一个简单原则:未推送的提交可以考虑 reset,已推送的共享提交优先考虑 revert。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。