Git 撤销三件套:reset、revert、checkout 到底怎么选
写代码免不了手滑:刚提交就发现改错了文件,或者还没提交就想把一团乱改丢掉。Git 里负责“反悔”的命令主要有三个:checkout、reset、revert。名字像,干的事完全不同,用错一个就可能丢代码。先说结论:还没提交的改动用 checkout(或 restore),只在本地的错误提交用 reset,已经推到远端的错误提交用 revert。
一、checkout:只动工作区,不动历史
git checkout -- <文件>(新版 Git 推荐 git restore <文件>)的作用是把工作区的文件还原成暂存区/最近提交的样子。它不改提交历史,也不碰暂存区之外的东西,适合“我还没 add,这段改动不要了”的场景。注意它不问确认,执行前先 git diff 看一眼要丢的是什么;重要改动先 git stash 存一份再丢,留条后路。
二、reset:移动 HEAD 指针,适合还没推出去的提交
git reset 本质是把当前分支的 HEAD 挪到另一个提交,附带决定工作区和暂存区跟不跟:--soft 只挪指针,改动全留在暂存区,适合“提交信息写错了/漏了文件,想重新提交”;--mixed(默认)挪指针并清空暂存区,改动留在工作区,适合“这次提交拆得不对,想重组”;--hard 指针、暂存区、工作区三者一起重置,改动直接消失,适合“本地这一串全不要了”。reset 改写历史,所以只对还没 push 的提交用;已经推到远端的提交用 reset,队友一拉代码就会冲突,甚至把别人的提交顶掉。
三、revert:用一次新提交“抵消”旧提交,适合已公开的历史
git revert <提交号> 不删历史,而是生成一个内容正好相反的新提交,把那次改动抵消掉。历史保持完整,队友拉取也不会乱,线上出问题回滚首选它。代价是历史里会多一条“撤销某某提交”的记录,显得啰嗦,但安全永远比好看重要。如果要撤销的是一串连续提交,git revert <旧>..<新> 可以一次处理,中间冲突按提示解决即可。
一张表记住区别:checkout 不动历史、只丢工作区改动;reset 挪动指针、改写本地历史;revert 不删历史、用新提交抵消。判断流程就三问:提交了吗?没提交用 checkout;提交了但只在本地?用 reset;已经 push 给别人了?用 revert。
最后两条保命习惯:第一,reset --hard 之前一定 git status 确认工作区没有未保存的重要改动,拿不准就先 git stash;第二,公共分支上永远不要 reset --hard + 强推,宁可多一条 revert 记录,也别让队友的本地仓库陷入混乱。反悔不可怕,可怕的是用错工具把后悔药变成新事故。
- 点赞
- 收藏
- 关注作者
评论(0)