历史改写与故障恢复
这一组命令会移动提交历史或修改已有提交。它们适合清理本地分支历史,但在已经推送并被他人基于其开发后,要先确认协作影响。
git reset HEAD~1
git reset --mixed HEAD~1用途:撤销最近一次提交,但保留文件修改在工作区中。
适用场景:
- 刚提交完发现提交范围不对,想拆分后重新提交。
- 提交消息或文件组合不合适,但改动本身还要保留。
说明:
HEAD~1表示沿第一父提交回退一代。--mixed会移动分支指针并重置 index,但保留工作区修改;它也是省略模式时的默认值,这里显式写出以便审查。
常见后续:
git status
git add -p
git commit -m "new message"git rebase -i HEAD~N
git rebase -i HEAD~5用途:交互式编辑最近 N 个提交,可以重排、合并、改消息或删除提交。
官方 cheat sheet 中用于 squash 示例的写法是:
git rebase -i HEAD~6实际使用时按你要编辑的提交数量调整 N。如果目标是处理最近 5 个提交,常见写法是 HEAD~5;如果想把更早的基线提交也放进编辑列表,就需要把范围扩大。
常见操作词:
| 操作 | 含义 |
|---|---|
pick | 保留该提交 |
reword | 保留提交内容,但修改提交消息 |
edit | 停在该提交,允许修改内容 |
squash | 合并到前一个提交,并保留消息编辑机会 |
fixup | 合并到前一个提交,丢弃当前提交消息 |
drop | 删除该提交 |
会改写提交 ID
rebase 会生成新的提交 ID。如果这些提交已经推送到共享分支,改写前要确认团队流程。
冲突期间的闭环:
git status
git add -- resolved-file.md
git rebase --continue如果基线、顺序或目标选择错误,应中止而不是继续叠加修复:
git rebase --abort
git status --short --branchsquash 最近多个提交
交互式 rebase 打开后,通常保留第一条为 pick,把后续想合并进去的提交改为 fixup 或 squash。
示意:
pick 1111111 first change
fixup 2222222 small fix
fixup 3333333 typo fix完成后 Git 会把这些提交合并成更少的提交。
git reflog BRANCHNAME
git reflog BRANCHNAME用途:查看某个分支引用曾经指向过哪些提交。它常用于找回 rebase、reset 或误删分支前的位置。
适用场景:
- rebase 失败或结果不对,想回到之前的提交。
- 分支被误删后想找回最后的提交 ID。
示例:
git reflog main
git reflog说明:
- 不带分支名的
git reflog通常查看当前HEAD的移动历史。 - reflog 是本地记录,不等同于远程仓库历史。
- reflog 会过期,也可能被清理;默认策略通常让 reachable 条目约 90 天、unreachable 条目约 30 天后过期,配置可改变。
- 删除分支也会删除该分支自己的 reflog。
HEADreflog 可能仍提供线索,但不能保证永久恢复。
先创建恢复引用,再决定是否移动当前分支:
git reflog
git branch recovery/before-rewrite 'HEAD@{1}'
git show recovery/before-rewrite这比立刻 hard reset 更容易复核,也保留了当前分支现场。
Reset 三种常见模式
| 模式 | 移动当前分支 | 重置 index | 覆盖工作区 | 典型边界 |
|---|---|---|---|---|
--soft | 是 | 否 | 否 | 重新组织尚未共享的最近提交 |
--mixed | 是 | 是 | 否 | 取消提交并重新暂存 |
--hard | 是 | 是 | 是 | 仅可丢弃隔离仓库;会丢未提交内容 |
reset 的效果还受目标提交和路径形式影响。不要只记“撤销”二字,先判断要移动引用、index 还是工作区。
git reset --hard <commit>
git reset --hard 'HEAD@{1}'用途:把当前分支、暂存区和工作区强制回到指定提交。
典型恢复流程:
git reflog
git branch recovery/before-hard-reset 'HEAD@{1}'
git reset --hard 'HEAD@{1}'高风险操作
这会丢弃当前工作区和暂存区修改,还可能删除阻碍目标树写入的未跟踪路径。只有在可丢弃的隔离仓库、已建立恢复引用且明确不需要当前本地改动时才使用。
git commit --amend
git commit --amend用途:修改最近一次提交。可以改提交消息,也可以把新暂存的文件补进上一条提交。
适用场景:
- 刚提交后发现消息有错。
- 刚提交后发现漏加一个文件,且还没推送或可以安全改写。
补交文件示例:
git add forgotten-file.md
git commit --amend如果只想改消息:
git commit --amend -m "new message"注意:amend 会替换最近一次提交,提交 ID 会变化。
参考资料
按 Git 2.55.0 官方文档核验,获取日期:2026-07-14。