Git 常见误操作急救手册|最全、最安全、一看就懂的后悔药指南(珍藏版)

0 阅读10分钟

前言

在日常开发中,几乎每个程序员都会遇到这样的崩溃瞬间:

  • 刚写完的代码,git reset --hard 直接清空,还没推送
  • 提交错分支,把 dev 代码写到了 master
  • 不小心 git push -f 强制推送,覆盖了别人代码
  • 合并代码把别人提交弄没了
  • 删错分支、删错文件、回滚错版本
  • 冲突没解决就提交,导致整个分支异常

Git 虽然强大,但很多命令带有破坏性,一旦用错,很容易造成代码丢失、分支混乱、线上故障。

而绝大多数人遇到问题第一反应是:慌、重装软件、复制项目、甚至删库重拉。

其实 Git 几乎所有误操作都能救回来,Git 本身设计了非常完善的 “后悔机制”。

这篇文章,我把开发中 99% 会遇到的 Git 误操作全部整理成一份急救手册,包含:场景重现、错误命令、正确修复命令、底层原理、详细解释、避坑提醒。你遇到问题直接打开这篇文章,对照步骤执行,就能安全恢复。

全文无废话、纯实战、可直接当工作手册收藏。


一、阅读本文你能学到什么

  1. 写错提交信息,怎么改?
  2. 刚提交就后悔,想撤回这次 commit 怎么办?
  3. 不小心 reset --hard 删掉了未提交代码,怎么找回?
  4. 推送到远程后发现错了,如何安全回滚,不坑队友?
  5. 合并分支丢失代码、丢提交,如何找回?
  6. 删错本地 / 远程分支,如何恢复?
  7. 冲突处理错误、 stash 丢失、pull 覆盖代码。
  8. git push -f 强制覆盖远程,如何抢救?
  9. 把敏感信息(密码、密钥)提交了,如何彻底清除?
  10. 各种 “手贱” 操作的统一急救思路。

二、Git 急救核心思想(先看懂这个,所有问题都会)

Git 有三条最重要的真理:

  1. 只要你执行过 commit,代码几乎永远不会丢
  2. 只要没 push 到远程,所有操作都能安全撤回
  3. 所有丢失的提交,都能通过 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。

急救步骤(万能救命法)

  1. 查看所有操作历史:

plaintext

git reflog

  1. 找到你误操作之前的那个 commit id
  2. 直接恢复:

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 分支名

急救

  1. 查看 reflog

plaintext

git reflog

  1. 找到该分支最后一次 commit
  2. 恢复分支:

plaintext

git checkout -b 恢复的分支名 commitId


十一、场景 9:误删远程分支,如何恢复

误操作

plaintext

git push origin --delete 分支名

急救

  1. 本地找到最后一次 commit
  2. 重新推送到远程:

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 代码时,被自动合并覆盖了本地代码

急救

  1. 立刻不要动!
  2. 使用 reflog 找到 pull 之前的版本:

plaintext

git reflog

  1. 重置回去:

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 强制覆盖了远程分支

急救步骤

  1. 自己本地不要乱动、不要拉代码
  2. 用 reflog 找到被覆盖前的正确 commit
  3. 本地 reset 到正确版本
  4. 再次强制推回去(抢救)

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:提交时把别人的代码一起提交了

急救

  1. 软重置回去:

plaintext

git reset --soft HEAD~1

  1. 取消暂存不需要的文件
  2. 重新单独提交自己的代码

二十一、Git 急救万能万能公式(背下来)

所有丢失代码、误删、误重置、丢提交,统一急救流程:

  1. 立刻停止操作,不要 pull、不要 push、不要重启
  2. 执行:

plaintext

git reflog

  1. 找到你想要回到的那个状态的 commit id
  2. 执行:

plaintext

git reset --hard 目标commit

99% 的灾难性误操作,这一招都能救。


二十二、Git 最容易踩坑的 10 条铁律(工作必看)

  1. 公共分支(master/dev)永远不要 reset + push -f
  2. 改提交信息 --amend 只能在未推送时用
  3. reset --hard 会清空工作区,不确定就先用 stash
  4. 代码一定要经常 commit,只要 commit 就不会丢
  5. pull 之前先 stash,避免被覆盖
  6. 冲突不要直接保存完事,一定要逐行检查
  7. 不要在主分支直接开发,一定要开功能分支
  8. 敏感配置不要提交,可以用 .gitignore
  9. 删分支前,先确认是否合并、是否有人在用
  10. 任何灾难性问题,先想到 reflog,而不是慌

二十三、总结

Git 不是玄学,所有操作都有逻辑、都有后悔药。绝大多数 “代码丢失”,不是真丢了,只是你不会用 reflog。

这篇手册覆盖了:

  • 撤回 commit
  • 修改提交信息
  • 撤销 add
  • 重置丢失代码
  • 安全回滚远程
  • 恢复删除分支
  • 找回 stash
  • 取消合并、取消 rebase
  • 解决冲突错误
  • 强制推送覆盖抢救
  • 彻底清除敏感文件
  • 万能急救流程

基本包含了工作 99% 的 Git 灾难场景

建议你:收藏这篇文章,加到浏览器书签、加到团队文档。以后遇到任何 Git 误操作,打开这篇手册,按步骤执行,安全、稳妥、不背锅、不删库、不跑路。