git revert和git reset的区别【对比】
别用 git reset --hard 去回滚别人已经拉过的提交——这是最常踩的坑,也是唯一必须先说清楚的事。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
在团队协作中,选错回滚命令的代价可不小。简单来说,git revert 和 git reset 的核心区别,就在于它们对待提交历史的态度截然不同。
git revert 会生成新提交,不改历史
你可以把 git revert 理解成一次“反向打补丁”的操作。它会对目标提交的所有变更,执行一次逻辑上的逆操作,然后将这个逆操作的结果,作为一个全新的提交保存下来。
这样一来,原来的错误提交依然安安静静地躺在历史记录里,只是它的影响被后来新增的这个“撤销提交”给抵消了。这种策略有几个明显的好处:
- 协作友好:它天生适合那些已经推送到远程仓库、并且可能有其他同事已经拉取过的分支,比如
main或develop。 - 历史清晰:执行后,你在
git log里会看到两个相邻的提交:一个是当初的错误操作,另一个就是这次撤销操作。整个来龙去脉一目了然。 - 合并安全:后续如果需要合并一些老的分支,Git 能够识别出“这个变更已经被撤销过了”,从而避免重复引入已经被回滚的修改。
- 命令示例:撤销单个提交用
git revert abc1234;撤销一段连续的提交则用git revert abc1234..def5678(注意这个范围是左开右闭的)。
git reset 会移动 HEAD,直接删掉提交记录
如果说 revert 是“做减法抵消”,那 reset 就更像是“让时光倒流”。它的本质是把当前分支的指针(HEAD)直接挪到某个更早的提交上,让后面的提交暂时“消失”。
不过,这里有个关键细节:reset 有三种模式,它们影响的“范围”不同,危险程度也天差地别。
git reset --soft abc1234:最温和的模式。只移动 HEAD 指针,暂存区和工作区的文件都保持原样。这适合你把几次提交打散后重新整理、打包。git reset --mixed abc1234(默认模式):移动 HEAD 指针,同时重置暂存区,但工作区的文件修改会保留。这通常用来撤销git add操作,把文件放回工作区。git reset --hard abc1234:威力最大也最危险。HEAD、暂存区、工作区全部被重置到目标提交的状态。所有未推送的后续修改,无论是否已暂存,都将被彻底清除。
重点来了:一旦你把提交推送到远程,再在本地执行 reset --hard 回滚,那么为了同步远程,你就不得不使用 git push --force 来强制覆盖远程历史。这会直接导致其他协作者在下次拉取代码时出现混乱,是协作开发中的大忌。
选哪个?看提交是否已共享
其实选择标准非常清晰,核心就一条:那个出问题的提交,有没有离开过你的本地,进入公共视野?
- 场景一:提交未共享。如果提交还在你本地,或者只在你自己用的特性分支上,用
git reset --hard是最快最干净的,可以彻底抹掉痕迹。 - 场景二:提交已共享。如果提交已经
push到了远程,并且其他同事可能已经基于它开始了新的工作,那么必须、也只能使用git revert。这是维护团队协作基石的基本操作。 - 场景三:只想合并提交,不想改内容。如果你只是想删掉最近几次提交的记录,但保留那些修改内容以便重新整理,那么
git reset --soft HEAD~2再git commit是个好选择。 - 场景四:误删了未跟踪的文件。如果不小心删了工作区的文件但还没
add,别用reset。可以用git checkout HEAD -- path/to/file来恢复(在 Git 2.23 及以上版本,更推荐使用git restore命令)。
容易被忽略的细节
当然,这两个命令也并非完美。有些细节,平时容易忽略,关键时刻却很重要。
git revert 并非总能一帆风顺。如果目标提交之后的代码发生了大量冲突性的修改,那么执行 revert 时可能会失败,需要你手动介入解决冲突。
而 git reset --hard 的危险性,有时比想象中更隐蔽。它清除的不仅仅是提交记录。举个例子,如果你刚刚 git add 了一个配置文件但还没 commit,此时执行 reset --hard,这个暂存状态也会被一并清空,且无法通过普通的日志找回。当然,最后一根救命稻草是 git reflog,你可以通过它定位到操作前的状态,并用 git reset --hard HEAD@{1} 之类的命令捞回来,但这毕竟增加了不必要的风险和心理负担。
说到底,工具本身没有好坏,关键在于在正确的场景使用正确的工具。把握住“是否已共享”这个分水岭,就能在代码回滚时做到既高效又稳妥。
相关攻略
VSCode终端默认是PowerShell而非Git Bash,因PowerShell是Windows官方现代shell,具备更好系统集成能力;Git Bash为第三方兼容层,需手动配置路径并设为默认终端。 为什么 VSCode 终端默认是 PowerShell 而不是 Git Bash 很多开发者
Git怎么查看文件在各版本间的变化_Git如何用diff对比两个commit的差异【命令】 git diff 怎么对比两个 commit 的差异 最直接的方法,就是使用 git diff 。这条命令会清晰地展示从 到 这个区间内,所有文件发生了哪些增删改。换句话说,你看到的就是 相对于 所做的全部改
Git不跟踪空目录,因其只记录含文件的目录结构;最可靠方案是在空目录中添加 gitkeep空文件并提交。 简单来说,Git本身并不跟踪空目录。所谓的“保留空文件夹”,其实是一种变通手段——而其中最可靠、也最通用的做法,就是在空目录里放一个名为 gitkeep 的空文件。 为什么 Git 不保存空文
Notepad++ 与 Git 集成:告别插件幻想,拥抱高效协同 开门见山地说,如果你正在为 Notepad++ 寻找一个可用的 Git 插件,恐怕要失望了。事实是,Notepad++ 本身并不支持 Git 插件——市面上既没有官方出品,也缺乏稳定的第三方集成。那些所谓的“Git 插件”传闻,通常指
Git怎么查看某行代码是谁写的_Git blame追溯代码作者教程【实战】 git blame 怎么看某行是谁写的 想快速定位某行代码的“最后经手人”?直接用 git blame 就对了。这个命令的设计初衷就是干这个的——它不负责展示完整的项目日志,也不翻陈年旧账,而是精准地将文件中的每一行,映射到
热门专题
热门推荐
教奶奶说普通话的一天 事情是这样的,自从我回了老家,奶奶就萌生了一个新念头——她想学说普通话。老人家那股子认真劲儿一上来,谁也拗不过,我自然也没能“幸免”,在她的软磨硬泡下,接下了这个“教学任务”。 可谁能想到,刚教了没几句,我就有点扛不住了。那种感觉,怎么说呢,就像一拳打在棉花上,使不上劲儿。脸上
酸、甜、苦、辣,还有一丝咸 酸、甜、苦、辣,同时还掺着一些咸咸的味道,几种味道混合在一起……别误会,这可不是在调制什么怪味豆的配方,而是在描述一种独特的“脾气”。包含了以上味道的怪味豆,或许还能用一个“香”字来概括;但若要用一个字来形容糅合了这几种特质的脾气,那毫无疑问,就是一个“怪”字了。 究竟怎
我的“美图”奶奶 家里有位71岁的“老学生”,心态却一点儿也不老,总爱琢磨点新鲜玩意儿。这不,最近她又解锁了一项新技能。 那天下午,我正用电脑处理照片,奶奶凑过来一看,眼睛顿时亮了。她对着屏幕上美化后的效果啧啧称奇,好奇地追问:“这是用了什么魔法?怎么照片一下子就精神了?”看她那副跃跃欲试的神情,我
公司新年团年联欢会开场主持词 (男)尊敬的各位领导, (女)亲爱的各位来宾, (男)各位朋友: (合)大家晚上好! (男)爆竹声声,传递着春的讯息;桃符处处,焕发出岁时的崭新气象。 (女)春风舞动门前的杨柳,喜雨催开满园的繁花。 (男)就在这辞别旧岁、迎接新春的美好时刻,我们欢聚一堂,共同拉开XX公
奶奶,一个多么熟悉、多么亲切的名字啊! 提起奶奶,你脑海中会浮现出怎样的形象?是慈祥的笑容,还是忙碌的背影?我记忆里的奶奶,脸上刻满了岁月的痕迹,中等身材,一双眼睛虽不大,却总是闪着炯炯有神的光。高高的鼻梁上架着一副老花镜,配上那身再普通不过的衣裳,整个人透着一股子朴实无华的气息。 勤劳,是刻在她骨





