Skip to content

Reset vs Revert

在 Git 中,resetrevert 都是用于撤销更改的命令,但它们的工作方式和适用场景有很大的不同。

核心区别

  • git reset时间倒流。它通过移动 HEAD 指针到指定的提交,从而“抹去”之后的提交记录。这会修改历史
  • git revert向前滚动。它创建一个新的提交,这个新提交的内容是用来抵消(撤销)指定提交的更改。这不修改历史,只是增加了新的历史。

1. Git Reset (重置)

git reset 主要用于本地未推送(push)的提交,或者你确定没有其他人基于你的分支进行开发的情况。

三种常用模式

模式命令HEAD 指针暂存区 (Index)工作区 (Working Dir)适用场景
--softgit reset --soft <commit>移动保留更改保留更改撤销了提交,但保留了代码和 git add 状态。适合想重新提交(修改 commit message 或合并多个 commit)。
--mixed (默认)git reset <commit>移动重置 (清空)保留更改撤销了提交和 git add。适合想重新挑选文件进行提交。
--hardgit reset --hard <commit>移动重置 (清空)重置 (清空)彻底毁灭。撤销所有更改,回到指定 commit 的状态。慎用!

示例图解

假设当前历史是:A -> B -> C (HEAD)

执行 git reset --hard B 后: 历史变为:A -> B (HEAD) Commit C 就像从未发生过一样(除非通过 reflog 找回)。

⚠️ 注意

千万不要对已经推送到公共仓库(Public Remote)的提交使用 git reset,这会导致其他协作者的历史混乱。

如果git reset后,版本回退的,无法直接push到远程仓库(因为远程仓库版本更新),git push -f覆盖推送即可,效果:远程仓库的版本也进行回退

2. Git Revert (回滚)

git revert 适用于公共分支或已经推送到远程仓库的提交。它是一种安全的撤销方式。

用法

bash
git revert <commit-hash>

示例图解

假设当前历史是:A -> B -> C (HEAD)

执行 git revert C 后: 历史变为:A -> B -> C -> D (HEAD)

其中 Commit D 的内容与 Commit C 的修改完全相反(例如 C 增加了一行,D 就删除那一行)。

优势

  • 安全:不会改变现有的项目历史。
  • 可追溯:撤销操作本身也有记录,方便日后查阅。

总结

特性Git ResetGit Revert
历史记录被修改(消失)被保留(新增撤销提交)
适用范围私有分支 / 本地未推送公共分支 / 已推送代码
风险较高(可能丢失代码或冲突)较低(只是增加新提交)
思维模型"如果我能回到过去...""我做错了,我要修正它..."