跳至内容
GitTree

Git 指南

撤消 git 重置、变基和提交:如何恢复(几乎)Git 中的任何内容

Git 很少会永远放弃工作。以下是如何撤消最后一次提交、修改、git reset --hard、变基、删除的分支或使用 git reflog 强制推送,以及 GitTree 的撤消如何一键处理大部分操作。

撰写者 Kodmora已更新 阅读 3 分钟
GitTree 提交菜单,包含挑选、还原、创建分支、标记和比较操作

要撤消 git 重置、变基或提交,请运行 git reflog,找到错误之前的条目并将分支指向该条目,例如使用 git reset --hard HEAD@{1}。 Git 会在引用日志中记录 HEAD 和每个分支的每一个移动,并且默认情况下甚至会将丢失的提交条目保留 30 天(分支上的提交为 90 天),因此提交的工作几乎永远不会消失。唯一真正的例外是你从未参与过的工作。

以下是每个常见错误的解决方法。每个命令都是纯 Git,并且在 macOS、Windows 和 Linux 上的工作方式相同。在 Windows 上,在带有 Git for Windows 的 Git Bash 中运行它们:PowerShell 需要引用日志名称,例如带引号的 HEAD@{1},并且没有 grep。最后您将了解桌面 Git 客户端 GitTree 如何保留 19 种操作的恢复快照,因此大多数错误只需一键即可返回。

Git undo 备忘单:每个错误的命令

找到您的情况,然后在运行任何操作之前阅读其部分。 HEAD@{1} 表示“HEAD 在一步前的位置”;如果此后您运行过其他命令,请先使用 git reflog 查找正确的数字。

撤消常见 Git 错误的命令
错误命令留意
最后一次提交,保留更改git reset --soft HEAD~1仅适用于您尚未推送的提交
最后一次提交,已经推送git revert HEAD添加取消旧提交的提交
糟糕的git commit --amendgit reset --soft HEAD@{1}在 HEAD 再次移动之前运行它
git reset --hardgit reset --hard HEAD@{1}未提交的更改不在引用日志中
完成的变基git reset --hard ORIG_HEAD下一次重置、合并或变基会覆盖 ORIG_HEAD
本地合并git reset --hard ORIG_HEAD推送后,使用 git revert -m 1 <merge>
已删除的分支git branch <name> <hash>哈希值位于删除消息或引用日志中
掉落的藏品git stash apply <hash>哈希值位于丢弃消息中
强力推git push --force-with-lease origin <hash>:main警告任何介入其中的人

Git reflog 解释:每个命令下的安全网

reflog(参考日志)是一个私人日记,记录了 HEAD 和您的分支提示所指向的位置。每次提交、签出、重置、合并、变基、修改和拉取都会添加一行,远程跟踪分支(例如 origin/main)也会添加一行。它仅存在于您的本地 .git 文件夹中:它永远不会被推送,并且新的克隆以空克隆开始。

git reflog
git reflog show main
git reflog --date=relative

变基后的典型 git reflog 如下所示,最新条目在前:

6c55495 HEAD@{0}: rebase (finish): returning to refs/heads/feature-login
6c55495 HEAD@{1}: rebase (pick): Validate the email field
cb6e15e HEAD@{2}: rebase (pick): Add the login form
2c44bc3 HEAD@{3}: rebase (start): checkout main
595b83d HEAD@{4}: commit: Validate the email field

向下阅读到错误发生之前的最新行:此处为 HEAD@{4},是在 rebase (start) 之前进行的提交。在 Git 需要提交的任何地方使用它的哈希值或该名称; main@{2.hours.ago} 也有效。条目会在 90 天后过期,对于没有分支可以到达的提交,则在 30 天后过期,并且当条目存在时,git gc 会保留其提交。

分四步使用 git reflog 恢复丢失的提交

  1. 列出引用日志

    对一个分支运行 git reflog 或 git reflog show <branch>,并记下错误发生之前的最新条目。

  2. 检查提交

    运行 git log --oneline -5 HEAD@{4} 以检查这是否是您想要恢复的状态。一切还没有改变。

  3. 将其保存在救援分支上

    运行git branch rescue HEAD@{4}。您的文件保持原样,并且提交不会再过期。

  4. 把你的分支移回来

    提交或隐藏您仍然需要的任何内容,在损坏的分支上运行 git reset --hard rescue,然后使用 git branch -d rescue 删除帮助程序。

Git 撤消上次提交:软重置、混合重置或硬重置

如果提交仍然仅在您的计算机上,则 git reset 将分支向后移动一次提交。该模式决定其变化会发生什么:

git reset --soft HEAD~1
git reset HEAD~1
git reset --hard HEAD~1
  • --soft 保持更改暂存,准备再次提交:非常适合修复消息或添加被遗忘的文件。
  • --mixed(默认值)将更改保留在工作文件夹中,未暂存,以便您可以拆分提交。
  • --hard 会在提交时丢弃更改以及任何未提交的编辑。 reflog 会将提交保留一段时间,但请三思。

如果您已经推送了它,请不要重写它:git revert HEAD 记录取消它的新提交。免费课程 推送后恢复错误 涵盖了恢复和其他安全返回方式。

撤消 git commit --amend

修改将提交替换为新的提交;原始内容保留在转发日志中。修改后,git reset --soft HEAD@{1} 将分支放回原始分支,并保留修改添加的内容。稍后,在 git reflog 中找到 commit (amend) 行并使用其下面的条目。

git reset --soft HEAD@{1}

如何撤消 git Reset --hard

硬重置会移动分支并覆盖您的文件,但它删除的提交仍然在 Git 的对象数据库中。引用日志将移动显示为 reset: moving to HEAD~2,其下方的行是您所在的位置。如果重置是您的最后一个命令,这将使一切恢复:

git reflog
git reset --hard HEAD@{1}
git fsck --lost-found

如何撤消 git rebase

如果变基因冲突而停止,则 git rebase --abort 将分支、索引和文件返回到原来的位置。如果完成了,你有两条路回去。当变基开始时,Git 将 ORIG_HEAD 指向旧提示,因此随后 git reset --hard ORIG_HEAD 会撤消它。分支自己的引用日志仍然更坚固:变基仅在 rebase (finish) 处移动分支一次,因此 feature-login@{1} 是与原来完全相同的分支。当变基或择优选择暂停时,课程[继续、跳过或中止活动操作](/zh/tutorial/ continue-skip-abort) 解释了每种退出方式。

git rebase --abort
git reset --hard ORIG_HEAD
git reset --hard feature-login@{1}

如果您已经推送了重新设置的分支,则恢复它需要强制推送(见下文)。要有意重写历史记录,请阅读我们的 Git GUI 中的交互式变基 指南。

撤消 git 合并

合并还会将旧提示保留在 ORIG_HEAD 中,因此 git reset --hard ORIG_HEAD 会撤消您尚未推送的提示。如果发生冲突,git merge --abort 可以帮助您摆脱困境,或者按照我们的指南来解决 Git 合并冲突。推送的合并通过 git revert -m 1 <merge-commit> 恢复;稍后再次合并该分支不会恢复这些更改,除非您恢复恢复。

git merge --abort
git reset --hard ORIG_HEAD
git revert -m 1 <merge-commit>

恢复已删除的 Git 分支(以及删除的存储)

删除分支会删除名称,而不是提交。 git branch -D 打印分支指向的提示,并从该哈希再次创建分支将其恢复:

git branch feature-login 1a2b3c4
git reflog | grep "moving from feature-login"

失去了输出? HEAD 的转发仍然记得。第二个命令找到 checkout: moving from feature-login to main;高一个数字的条目(如果匹配为 HEAD@{5},则为 HEAD@{6})是分支的最后一次提交。如果分支仍在远程,则 git branch feature-login origin/feature-login 会更快。要返回一个提交而不是整个分支,请将其与cherry-pick一起应用。

恢复掉落的藏品

git stash drop 和 git stash pop 打印他们删除的存储的哈希值,然后 git stash apply <hash> 将其恢复。如果没有哈希值,Git 的文档建议搜索无法访问的存储提交;它发现用默认的“WIP on ...”消息保存的存储:

git stash apply 9d668e5
git fsck --unreachable | grep commit | cut -d' ' -f3 | xargs git log --merges --no-walk --grep=WIP --oneline

如何撤消强制推送

强制推送会将远程分支替换为您的分支,因此仅在远程上的提交将被删除。您的远程跟踪分支也保留引用日志:origin/main@{1} 是推送之前远程分支所在的位置,正如您上次看到的那样,推送输出打印与 old...new 前半部分相同的哈希值。

git reflog show origin/main
git push --force-with-lease origin 1a2b3c4:main

如果遥控器自您上次获取后发生了移动,则 --force-with-lease 会拒绝推送,因此您不会意外覆盖队友的修复。您从未获取的提交从未在您的计算机上;谁推动了他们,谁就可以再次推动他们。然后告诉任何介入其中的人。 恢复推送错误的视频 显示了整个修复过程。

GitTree一键撤消:19种操作的恢复快照

上面的所有内容也适用于 GitTree:它运行您安装的 Git(2.39 或更高版本),并且其内置终端在提交图下打开您自己的 shell。添加内容:GitTree 在 refs/ogt/trash 下保留 19 种操作的恢复快照,在运行之前保存破坏性步骤将删除的任何内容,工具栏中的“撤消”按钮可反转最后一步。

撤消涵盖提交和修改、签出、重置、变基(也是交互式的)、丢弃的文件、块和行、删除的分支和标签、清理未跟踪的文件等等。对于从 GitTree 运行的硬重置,快照也会保存您未提交的更改,而普通的 git reset --hard 无法恢复这些更改。

撤消和重做位于 GitTree 工具栏中,图表中的提交菜单为任何提交提供重置、恢复和交互式变基。
撤消和重做位于 GitTree 工具栏中,图表中的提交菜单为任何提交提供重置、恢复和交互式变基。

19 个中的两个被保留而不是被颠倒。用力推送会更改遥控器,只有另一次推送才能将其更改回来,因此 GitTree 保留其替换的尖端并将推送留给您(它始终使用 --force-with-lease 进行强制推送)。删除的存储会被快照,但撤消还不能恢复它。 GitTree 还拒绝会覆盖以后工作的撤消,并说明原因。正常推送无法从应用程序撤消;而是恢复。

Reset 命名了它的三种模式:Soft 保留所有更改,Mixed 将它们保留在工作文件夹中,Hard 在撤消可以恢复的快照后丢弃它们。
Reset 命名了它的三种模式:Soft 保留所有更改,Mixed 将它们保留在工作文件夹中,Hard 在撤消可以恢复的快照后丢弃它们。

如何撤消 GitTree 中的重置、变基或删除分支

  1. 照常工作

    像平常一样重置、变基、丢弃或删除分支。 GitTree 首先拍摄快照;硬重置对话框是这样说的。

  2. 单击撤消

    单击工具栏中的“撤消”或从命令选项板 (Ctrl/⌘+Shift+P) 运行它。其工具提示为该步骤命名,例如“撤消:删除分支功能登录”;无法撤消的步骤说明了原因。

  3. 通过 reflog 进一步追溯

    撤消涵盖了 GitTree 本身运行的内容。对于在终端中键入的命令,请从选项板运行“查看引用日志...”,选择一个条目并选择“恢复为分支”。

  4. 在推送之前检查图表

    提交图 将分支显示回原来的位置,因此您可以在任何内容离开计算机之前确认结果。

让每个 Git 错误都可逆转的习惯

  • 尽早提交,甚至是混乱的。只有提交的工作才会到达引用日志;稍后通过交互式变基来整理它。
  • 在进行有风险的编辑之前进行分支。 git branch backup/before-rebase 无需任何费用且永不过期。
  • 切勿使用普通的 `--force`。 --force-with-lease 不会覆盖您未见过的提交。
  • 恢复共享历史记录,重置私人历史记录。其他人拉取提交后,将其恢复。
  • 保持 Git 最新。 GitTree 需要 Git 2.39 或更高版本,Ubuntu 22.04 发布 2.34;请参阅如何在 Ubuntu 上升级 Git。

还在打字和点击之间做出选择吗?阅读 Git GUI 与命令行,或从 Git for Beginners, with a GUI 开始。

GitTree 有一个免费计划,涵盖所有 Git 功能,包括私有存储库,适用于 macOS 13 或更高版本、Windows 10 和 11 (x64) 以及 64 位 Linux(x86_64:Ubuntu 22.04+、Debian 12+),并且 AI 助手 Nour 随 GitTree Pro 一起提供(请参阅定价)。它需要 Git 2.39 或更新版本以及 GitTree 帐户才能登录。从下载页面 获取它,或查看它如何在 Linux 上运行。

常见问题

如何撤消 git reset --hard ?

运行 git reflog 并找到 reset: moving to … 下面的行;那就是你的分行所在的地方。如果重置是您的最后一个命令,则 git reset --hard HEAD@{1} 将恢复删除的提交。您从未提交的更改不会出现在引用日志中,因此 Git 无法恢复它们;如果您在 GitTree 中运行了硬重置,则其撤消操作会从首先拍摄的快照中恢复它们。

如何撤消上次提交但保留更改?

运行 git reset --soft HEAD~1 来暂存更改,或运行 git reset HEAD~1 来将更改保留在工作文件夹中。两者都只重写您的本地分支,因此将它们用于尚未推送的提交。对于推送的提交,运行 git revert HEAD,这会添加一个取消它的提交。

git rebase 完成后如何撤消它?

变基后,git reset --hard ORIG_HEAD 将分支返回到其旧的尖端。如果此后您运行过其他命令,请使用 git reset --hard <branch>@{1}:变基仅在分支完成时移动一次。如果您已推送了重新设定的分支,请使用 --force-with-lease 推送恢复的分支。

git reflog 会将丢失的提交保留多长时间?

丢失的提交,即没有分支再到达的提交,默认情况下将其引用日志条目保留 30 天;过去 90 天仍在分支上的提交条目。当条目存在时,垃圾收集会保留其提交。要无限期地保留提交,请在其上放置分支或标签,例如 git branch rescue <hash>,因为 Git 永远不会删除分支指向的提交。

git reset --hard 后可以恢复未提交的更改吗?

通常不能单独使用 Git。引用日志记录的是提交,而不是工作文件夹中的编辑,因此请检查编辑器的本地历史记录。暂存文件可能会作为 git fsck --lost-found 写入 .git/lost-found/other/ 的悬空对象而存在,而无需文件名。 GitTree 在其自身硬重置之前快照未提交的更改。

如何撤消强制推送?

找到您替换的远程提示:git reflog show origin/main 将其列为 origin/main@{1},推送输出将其显示为 old...new 中的第一个哈希。然后运行git push --force-with-lease origin <hash>:main。如果推送覆盖了您从未获取过的提交,请询问推送它们的人再次推送它们。

GitTree 可以撤消 git 推送吗?

不可以。正常推送无法从 GitTree 撤消;相反,恢复提交。对于强制推送,GitTree 会将其替换的远程提示保留在恢复快照中,因此不会丢失任何内容,但恢复远程需要另一次推送。撤消涵盖本地操作,例如提交、重置、变基、签出和分支删除。

git reflog 是否与我的团队共享?

不会。引用日志仅存在于您的本地 .git 文件夹中。它永远不会被推送,获取不会带来任何其他人的,并且新的克隆从空克隆开始。因此,队友丢失的提交只能在他们的计算机上恢复,并且即使有人覆盖远程分支,您的引用日志也会保留您的提交。

来源

有关其他产品的声明已根据其位于 2026年10月23日 的官方页面进行了检查。价格和功能发生变化;供应商的页面是事实的来源。