历史改写与故障恢复

这一组命令会移动提交历史或修改已有提交。它们适合清理本地分支历史,但在已经推送并被他人基于其开发后,要先确认协作影响。

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 --branch

squash 最近多个提交

交互式 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。HEAD reflog 可能仍提供线索,但不能保证永久恢复。

先创建恢复引用,再决定是否移动当前分支:

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。