Git 救命指南:12 个迟早会用到的命令(改错 / 误删 / 丢代码全场景修复)

Git 平时用就那么几个:addcommitpushpull。但总有那么些时刻——提交错了、文件加错了、改动没了、分支删了、代码"丢了"——你会突然需要一些平时根本不碰的命令。而那个时刻你通常正手忙脚乱、没心情现搜文档。

这篇把那些"迟早会用到"的救命操作系统整理出来,12 个高频场景 + 2 个进阶技巧,每个都给命令、讲清楚原理、标好坑。建议收藏,真出事的时候照着做就行。

1. 改错了最后一次提交

提交信息打错字了,或者提交完发现漏了个文件。只要这次提交还没 push,都能干净地补救:

git commit --amend                 # 打开编辑器改提交信息

如果只是想把漏掉的文件补进去、信息不用改:

git add 漏掉的文件
git commit --amend --no-edit       # 把文件补进上次提交,信息不变

:--amend 的本质是"用一次新提交替换掉最后一次提交"。已经 push 到共享分支的提交别 amend——你本地的提交和远程对不上了,再推就得强推,会影响别人。amend 只对"还没推出去的"提交安全。

2. 撤销提交,但改动要保留

不小心把东西 commit 了,想把"提交"这个动作撤销、但代码改动一点不能丢:

git reset --soft HEAD~1            # 撤销提交,改动留在暂存区,随时重新提交
git reset HEAD <file>             # 把某个文件移出暂存区(改动还在)

--soft 是关键:它只回退"提交"这个动作,你的改动原封不动留在暂存区,重新整理一下再提交即可。--mixed(默认值)则会把改动退到工作区。记住:soft 退到暂存区,mixed 退到工作区,改动都还在。

3. 彻底丢弃提交和改动

这次提交和它带的改动你都确定不要了:

git reset --hard HEAD~1            # 撤销提交 + 丢弃改动(危险!不可逆)

--hard 会把提交和工作区改动一起抹掉。这是最危险的一条,按下去之前务必想清楚。不过别太怕——即使误用了,只要那些提交曾经存在过,第 5 条的 reflog 还能把它们捞回来。

4. 丢弃工作区的改动,回到没动过的样子

git restore <file>                # 丢弃工作区某个文件的改动
git restore .                     # 丢弃所有未暂存的改动(危险,想清楚再按回车)

git restore . 会把所有未暂存的改动一笔勾销,而且这些改动不进任何记录、不可恢复。拿不准的话,先 git stash(见第 6 条)留个后路,确认不要了再 drop。

5. 代码"丢了"——真正的救命稻草

这是整篇里最值得记死的一条:只要你 commit 过,在 Git 里就几乎没有真正丢失的代码。

reset --hard 了、误删了分支、rebase 搞砸了、amend 覆盖了……只要那些提交曾经存在过,git reflog 都能帮你找回来。它记录了 HEAD 的每一次移动:

git reflog                        # 列出 HEAD 的每一次移动,带 hash
git reset --hard <出事前那条记录的hash>   # 时光机:回到任意历史状态

在 reflog 列表里找到"出事之前"的那个状态,把它的 hash 拿去 reset --hard,就回去了。很多人用 Git 多年都不知道 reflog 的存在,直到第一次靠它捞回半天的工作量——然后这辈子都忘不掉。

6. 临时存放改动,干净地切分支

正在 A 分支改东西改到一半,突然要切去 B 分支处理急事,但手里的改动还没到能提交的程度:

git stash                         # 把当前改动打包收起,工作区瞬间变干净
git stash pop                     # 切回来后,把改动倒出来接着干
git stash list                    # 查看存了哪些

git stash 把当前改动打包收起来,工作区瞬间变干净,你可以随便切分支。事情处理完切回来,git stash pop 把改动倒出来接着干。它能存多个,git stash list 查看。这也是做任何"危险补救"之前给自己留后路的标准动作。

7. 只想要别人分支上的某一个提交

另一个分支上有一次提交,你只想要那一个 commit,不想把整条分支合过来:

git cherry-pick <commit-hash>     # 把指定的某次提交"摘"到当前分支

cherry-pick 会把指定的那次提交"摘"到你当前分支上。修了个 bug 想同步到多个分支、或者把某个功能从实验分支单独捞出来,都靠它。

8. 撤销一个已经 push 出去的提交

提交已经推到共享分支了,这时候千万别用 reset(那会改写历史,逼别人强行同步)。正确做法是用 revert:

git revert <commit-hash>          # 生成一个「反向提交」来抵消,历史不被改写,可安全推送

revert 不删除历史,而是新增一个"反向提交"来抵消目标提交的改动。历史是往前走的,所有人正常 pull 就行,不会有任何冲突灾难。记住这条铁律:没 push 的用 reset,已 push 的用 revert。

9. 提交到错的分支上了

本该提到 feature,结果手一抖提到了 main。把它搬回去:

# 假设刚才在 main 上误提交了,本该提到 feature
git log --oneline -1              # 记下这次提交的 hash
git reset --hard HEAD~1           # main 退回去
git checkout feature
git cherry-pick <刚才记下的hash>   # 把提交搬到 feature

思路就是"在错的分支上撤销、到对的分支上摘过来"——reset 和 cherry-pick 的组合拳。同样,前提是这次误提交还没 push。

10. 误删了分支

手滑 git branch -D 把一个还有用的分支删了。别慌,分支只是一个指向某次提交的指针,提交本身还在:

git branch                        # 先看分支没了
git reflog                        # 找到被删分支最后那次提交的 hash
git branch <分支名> <那个hash>     # 用 hash 把分支重新建出来

又是 reflog 救场。它能列出那个分支最后指向的提交 hash,你拿这个 hash 重新 git branch 一下,分支就回来了。

11. 已经提交的文件,想加进 .gitignore

很常见的失误:某个本地配置文件、日志文件、node_modules 已经被 commit 进仓库了,这时候光往 .gitignore 里加一行是没用的——Git 对已追踪的文件不看 .gitignore。得先让 Git "忘掉"它:

echo "config.local.js" >> .gitignore
git rm --cached config.local.js   # 从 Git 里移除追踪,但保留本地文件
git commit -m "stop tracking config.local.js"

git rm --cached--cached 很关键:它只把文件从 Git 的追踪里移除,本地文件本身不删。提交之后,这个文件就既留在你本地、又不再被 Git 管了。

12. 用二分法揪出引入 bug 的提交

"上周还好好的,现在坏了,中间几十个提交,到底是哪个搞坏的?"——靠肉眼一个个翻能翻到天黑。git bisect 用二分查找帮你定位:

git bisect start
git bisect bad                    # 当前版本是坏的
git bisect good <一个已知正常的旧commit>
# Git 自动二分检出,你测一次答一次 good / bad
# 几轮之后它会告诉你:是哪个 commit 引入了 bug
git bisect reset                  # 结束,回到原来的状态

它会自动在"已知正常"和"已知出错"之间二分,每次检出一个版本让你测、你回答 good 或 bad,几轮(log₂ 次)之后就能精确指出是哪个 commit 引入的问题。几十个提交,通常五六次就定位到了,堪称神器。

附:用交互式 rebase 整理提交历史

开发过程中难免留下一堆"修个错别字""再改改""哦又漏了"这种零碎提交。push 之前用交互式 rebase 把它们整理干净,提交历史会清爽很多:

git rebase -i HEAD~3              # 整理最近 3 次提交
# 编辑器里把某行的 pick 改成:
#   squash / s  —— 合并到上一条
#   reword / r  —— 改提交信息
#   drop   / d  —— 删掉这次提交
#   edit   / e  —— 停下来让你修改

同样的铁律:交互式 rebase 只对还没 push 的提交用,它会改写历史。整理自己本地的提交很好用,别拿去动共享分支。

写在最后:三条万能心法

这些命令的共同点是:平时用不上,用上时往往在救火。值得花十分钟把它们各跑一遍、心里有个底——真出事的时候,"知道有办法"和"完全懵了"是两种完全不同的体验。

最后给三条贯穿全篇的心法:

  • 动手补救前,先 git stash 或记下当前状态。给自己留后路,永远不亏。
  • 没 push 的随便折腾,已 push 的用 revert。这条线划清楚,就不会把队友拖下水。
  • 记住 git reflog 的存在。它是 Git 给你的后悔药,只要 commit 过,基本没有真的回不去的状态。
—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

JavaScript 防抖与节流彻底搞懂:原理、区别、手写实现 + 实战避坑指南

2026-5-14 16:04:43

技术教程

Flexbox 还是 Grid?2026 前端布局终极选择指南(附决策清单)

2026-5-14 16:32:30

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索