前言
在日常开发中,几乎每个程序员都会遇到这样的崩溃瞬间:
- 刚写完的代码,
git reset --hard直接清空,还没推送 - 提交错分支,把 dev 代码写到了 master
- 不小心
git push -f强制推送,覆盖了别人代码 - 合并代码把别人提交弄没了
- 删错分支、删错文件、回滚错版本
- 冲突没解决就提交,导致整个分支异常
Git 虽然强大,但很多命令带有破坏性,一旦用错,很容易造成代码丢失、分支混乱、线上故障。
而绝大多数人遇到问题第一反应是:慌、重装软件、复制项目、甚至删库重拉。
其实 Git 几乎所有误操作都能救回来,Git 本身设计了非常完善的 “后悔机制”。
这篇文章,我把开发中 99% 会遇到的 Git 误操作全部整理成一份急救手册,包含:场景重现、错误命令、正确修复命令、底层原理、详细解释、避坑提醒。你遇到问题直接打开这篇文章,对照步骤执行,就能安全恢复。
全文无废话、纯实战、可直接当工作手册收藏。
一、阅读本文你能学到什么
- 写错提交信息,怎么改?
- 刚提交就后悔,想撤回这次 commit 怎么办?
- 不小心
reset --hard删掉了未提交代码,怎么找回? - 推送到远程后发现错了,如何安全回滚,不坑队友?
- 合并分支丢失代码、丢提交,如何找回?
- 删错本地 / 远程分支,如何恢复?
- 冲突处理错误、 stash 丢失、pull 覆盖代码。
- 误
git push -f强制覆盖远程,如何抢救? - 把敏感信息(密码、密钥)提交了,如何彻底清除?
- 各种 “手贱” 操作的统一急救思路。
二、Git 急救核心思想(先看懂这个,所有问题都会)
Git 有三条最重要的真理:
- 只要你执行过 commit,代码几乎永远不会丢
- 只要没 push 到远程,所有操作都能安全撤回
- 所有丢失的提交,都能通过 reflog 找回来
记住一句话:git reset --hard 不是删代码,只是移动指针;git reflog 是所有误操作的最终救命稻草。
三、场景 1:刚刚 commit,发现提交信息写错了
场景
你执行了:
plaintext
git commit -m "add login page"
发现信息写错、漏字、描述错误,还没有 push。
急救命令
plaintext
git commit --amend
如果只想改消息,不改动代码:
plaintext
git commit --amend -m "正确的提交信息"
详细解释
--amend不会生成新的 commit,直接修改最近一次提交- 不会改变 commit hash,不会产生冗余提交
- 只能修改最后一次提交
- 如果已经 push 到远程,不能用这个命令,会导致分支不一致
注意
⚠️ 已经推送到远程的提交,禁止使用 --amend,否则无法正常推送。
四、场景 2:刚 commit,想撤回这次提交,代码保留
场景
你提交了,但想把代码撤回到 “暂存区”,继续修改,不删除代码。
急救命令
plaintext
git reset --mixed HEAD^
简写:
plaintext
git reset HEAD^
详细解释
-
HEAD^表示回到上一个版本 -
--mixed是默认参数:- 撤销 commit
- 撤销 git add
- 代码保留在工作区
-
你的代码完全还在,只是回到 “未提交” 状态
适用
- 提交太急,想拆分多次提交
- 想重新编辑代码再提交
五、场景 3:想撤销 commit,并且把代码放回暂存区
急救命令
plaintext
git reset --soft HEAD^
解释
- 撤销 commit
- 不撤销 add
- 代码留在暂存区
- 你可以直接再次 commit,不需要重新 add
六、场景 4:手贱执行 git reset --hard,删了未推送代码
场景(最崩溃)
plaintext
git reset --hard HEAD~1
执行完,本地最新代码直接消失,还没 push。
急救步骤(万能救命法)
- 查看所有操作历史:
plaintext
git reflog
- 找到你误操作之前的那个 commit id
- 直接恢复:
plaintext
git reset --hard 你找到的commitId
超详细解释
git reflog会记录你所有 HEAD 移动记录- 包括:commit、reset、merge、checkout、pull
- 哪怕你 hard 重置了,只要曾经 commit 过,记录永远存在
- reflog 是 Git 终极后悔药
重要
reflog 不会被提交,只在本地保存,默认 90 天。只要你没删仓库,就能找回来。
七、场景 5:已经 push 到远程,想安全回滚(不坑队友)
禁忌
绝对不要:
plaintext
git reset --hard xxx
git push -f
这会覆盖远程提交,团队共用分支直接爆炸。
正确安全回滚(生产环境标准做法)
plaintext
git revert 要回滚的commitId
解释
revert不会删除历史提交- 它会生成一个新的提交,用来抵消旧提交
- 远程分支历史完整、安全、可追溯
- 不会影响别人代码,不会造成冲突灾难
回滚最近一次提交
plaintext
git revert HEAD
适用
- 已推送到远程
- 公共分支、master、test、dev
- 线上发布回滚
八、场景 6:git add 错文件,想撤销 add
场景
你 git add . 把不该提交的文件加进去了。
撤销所有 add
plaintext
git reset HEAD .
撤销单个文件
plaintext
git reset HEAD 文件名
解释
- 只撤销暂存区
- 工作区代码不变
- 最常用、最安全
九、场景 7:想丢弃工作区修改,还原成仓库版本
场景
本地改乱了,想直接放弃所有修改,还原成最后一次提交。
急救
plaintext
git checkout -- 文件名
放弃所有修改
plaintext
git checkout .
⚠️ 注意:未 add、未 commit 的代码,会直接丢失,无法恢复!
十、场景 8:删错本地分支,想恢复
误操作
plaintext
git branch -D 分支名
急救
- 查看 reflog
plaintext
git reflog
- 找到该分支最后一次 commit
- 恢复分支:
plaintext
git checkout -b 恢复的分支名 commitId
十一、场景 9:误删远程分支,如何恢复
误操作
plaintext
git push origin --delete 分支名
急救
- 本地找到最后一次 commit
- 重新推送到远程:
plaintext
git push origin 本地分支名:远程分支名
只要有人本地还有这个分支,就能恢复。
十二、场景 10:git stash 储藏后,找不到代码了
场景
你 stash 了代码,后来切分支、合并,找不到了。
查看所有储藏
plaintext
git stash list
恢复最新储藏(不删除记录)
plaintext
git stash apply stash@{0}
恢复并删除记录
plaintext
git stash pop
彻底删除某个储藏
plaintext
git stash drop stash@{0}
清空所有储藏
plaintext
git stash clear
如果你不小心 drop 了储藏(急救)
plaintext
git fsck --no-reflog | grep commit
遍历所有悬空提交,找到储藏的 commit,再恢复。
十三、场景 11:pull 代码时,被自动合并覆盖了本地代码
急救
- 立刻不要动!
- 使用 reflog 找到 pull 之前的版本:
plaintext
git reflog
- 重置回去:
plaintext
git reset --hard 之前的commitId
以后避免
pull 前先储藏:
plaintext
git stash
git pull
git stash pop
十四、场景 12:合并分支(merge)后,发现代码乱了,想取消合并
如果你还没 push
plaintext
git reset --hard ORIG_HEAD
解释
- 执行 merge 前,Git 会自动保存指针到 ORIG_HEAD
- 一行命令直接回到合并前状态
十五、场景 13:rebase 中途混乱,想终止 rebase
plaintext
git rebase --abort
十六、场景 14:提交了密码、密钥、私密文件,想彻底从 Git 历史抹去
危险
简单 revert /reset 没用,历史依然存在。
彻底清除(全局重写历史)
plaintext
git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch 要删除的文件路径" \
--prune-empty --tag-name-filter cat -- --all
然后强制推送:
plaintext
git push origin --force --all
适用
- 泄露配置、密钥、token
- 必须彻底清除历史
十七、场景 15:不小心 git push -f 强制覆盖了远程分支
急救步骤
- 自己本地不要乱动、不要拉代码
- 用 reflog 找到被覆盖前的正确 commit
- 本地 reset 到正确版本
- 再次强制推回去(抢救)
plaintext
git reset --hard 正确commit
git push -f origin 分支
预防
- 公共分支禁止配置允许 force push
- 仓库设置分支保护
十八、场景 16:冲突解决错了,保存后想重新解决冲突
急救
plaintext
git merge --abort
或
plaintext
git reset --hard HEAD
重新拉取、重新合并。
十九、场景 17:想删除最近多次提交,但保留中间代码
方法:交互式变基
plaintext
git rebase -i HEAD~要回退的个数
把要删除的 commit 前面的 pick 改为 drop,保存退出。
⚠️ 只适用于未推送的提交。
二十、场景 18:提交时把别人的代码一起提交了
急救
- 软重置回去:
plaintext
git reset --soft HEAD~1
- 取消暂存不需要的文件
- 重新单独提交自己的代码
二十一、Git 急救万能万能公式(背下来)
所有丢失代码、误删、误重置、丢提交,统一急救流程:
- 立刻停止操作,不要 pull、不要 push、不要重启
- 执行:
plaintext
git reflog
- 找到你想要回到的那个状态的 commit id
- 执行:
plaintext
git reset --hard 目标commit
99% 的灾难性误操作,这一招都能救。
二十二、Git 最容易踩坑的 10 条铁律(工作必看)
- 公共分支(master/dev)永远不要
reset + push -f - 改提交信息
--amend只能在未推送时用 reset --hard会清空工作区,不确定就先用stash- 代码一定要经常 commit,只要 commit 就不会丢
- pull 之前先 stash,避免被覆盖
- 冲突不要直接保存完事,一定要逐行检查
- 不要在主分支直接开发,一定要开功能分支
- 敏感配置不要提交,可以用 .gitignore
- 删分支前,先确认是否合并、是否有人在用
- 任何灾难性问题,先想到 reflog,而不是慌
二十三、总结
Git 不是玄学,所有操作都有逻辑、都有后悔药。绝大多数 “代码丢失”,不是真丢了,只是你不会用 reflog。
这篇手册覆盖了:
- 撤回 commit
- 修改提交信息
- 撤销 add
- 重置丢失代码
- 安全回滚远程
- 恢复删除分支
- 找回 stash
- 取消合并、取消 rebase
- 解决冲突错误
- 强制推送覆盖抢救
- 彻底清除敏感文件
- 万能急救流程
基本包含了工作 99% 的 Git 灾难场景。
建议你:收藏这篇文章,加到浏览器书签、加到团队文档。以后遇到任何 Git 误操作,打开这篇手册,按步骤执行,安全、稳妥、不背锅、不删库、不跑路。