到目前为止,我们讨论的都是理想情况:您编写代码、创建提交、发起 Pull Request。但现实中常常会出岔子:忘了添加文件,提交说明里打错字,或者发现方向走偏了。本文会介绍如何用 IDE 工具处理最常见的问题。
示例和界面截图基于 JetBrains IDE;操作名称和位置可能因版本而异。练习时请使用单独的练习仓库。在实际项目中,请遵循项目关于分支、提交和推送更改的规则。
Claude Code 在项目中工作时,保存下来的历史记录有助于恢复到之前的状态。但 Git 不会记录每一次按键:未提交的更改可能会丢失。撤销前,请确认分支、选中的文件,以及是否留有需要的副本。
Rollback - 撤销本地更改
场景:您修改了一个文件,后来发现这些更改都不对,想快速恢复到最近一次提交时的状态。

使用 Rollback 功能:
- 在左侧面板打开
Commit标签页; - 在列表中找到要撤销更改的文件(也可以选中多个文件);
- 右键点击并选择
Rollback(或点击圆形箭头图标)。
IDE 会警告您选中的本地更改将会丢失。先查看 diff,并保存需要保留的内容。只有确实想丢弃这些更改时才确认 Rollback,然后检查结果。这会删除未提交的工作,并不会为它创建备份。
执行 Rollback 前,先把智能体的更改与同一文件里原有的更改区分开。Rollback 会将选中的文件恢复到最近一次提交(HEAD)的状态,并丢弃已暂存和未暂存的更改。这与不带标志的 git restore 不同:后者从索引取回内容,只会修改工作区文件。
Amend - 补充最近一次提交
场景:您刚点了 Commit,马上意识到忘记添加一个重要文件(例如更新后的测试),或者提交说明里有错字。如果提交还没有推送,可以使用 Amend。也可以另做一个修正提交,尤其是提交已经进入共享历史时。

要补充尚未推送的提交,请使用 Amend(补充/修正)功能:
- 在
Commit窗口中修改漏掉的文件,并勾选它; - 在 Commit Message 面板中找到 Amend 复选框(或点击齿轮图标 -> Amend Commit)并勾选;
- IDE 会带入上一次提交的说明,您可以编辑它;
- 点击
Commit。
Amend 会创建一个新提交来替代旧提交,因此它的标识符会改变。旧对象不会原地修改。如果旧提交已经推送且其他人正在使用,通常单独创建一个修正提交更合适。
有关此功能的更多信息,请参阅 JetBrains 官方教程。
Undo Commit
场景:您创建了一个提交,但还没有通过 Push 推送,随即发现自己太着急了。您希望这个提交从历史记录中消失,但更改仍留在编辑器里,以便继续工作。
使用 Undo Commit 功能:
- 打开历史记录,也就是底部的
Git -> Log标签页; - 找到当前分支(HEAD)上的最近一次提交,而不是简单地选整个提交图最上面的那一行,然后打开它的上下文菜单;
- 选择
Undo Commit。

选择更改列表(通常是 Default Changelist),然后点击 OK。该提交会从历史记录中消失,文件则以已修改状态回到 Commit 窗口。内容没有丢失,您可以继续编写代码。
Reset - 移动分支并处理文件状态
Reset Current Branch to Here... 是一个强大的工具,可以将分支指针移动到任意选定的提交。根据具体情况,它既可以温和地撤销最近的操作,也可能彻底抹掉有问题的代码。
场景 A - 撤销最近的本地提交
您在本地连续创建了几个提交(还没有 Push),后来发现这整段开发过程都走错了方向。
- 打开
Git -> Log标签页; - 找到您想回到的最近一个正常提交(也就是一系列错误提交之前的那个);
- 右键点击它,并选择
Reset Current Branch to Here...。
场景 B - 重置到服务器上的状态
您想根据远程分支恢复受 Git 跟踪的文件。先保存需要保留的本地工作,再执行 Fetch:origin/main 标签反映的是最近一次获取到的状态,并非服务器上持续更新的状态。如果当前有冲突操作,先解决并完成它,或者取消它;不要把 Hard 当成万能解法。
- 打开
Git -> Log; - 找到远程分支标记,通常是带紫色标签
origin/main的提交(或origin/your_branch_name)。这是服务器上最近一次已知的代码状态; - 右键点击该提交,并选择
Reset Current Branch to Here...。

重置模式
在重置窗口中谨慎选择模式。三种模式都会将当前分支移到选定的提交,但索引和工作区文件的处理方式不同:
- Soft 会保留工作区文件和索引。Mixed 会保留工作区文件,但将索引还原到选定的提交,因此差异仍处于未暂存状态。这两种模式并不相同,不过都能让您继续处理文件内容;
- Hard 会将索引和受跟踪文件恢复到选定的提交,并销毁其中未提交的更改。一般无关的 untracked 文件可能会保留,而妨碍恢复的路径则可能被删除。提交不会立即从所有存储中消失,但别指望之后还能把工作救回来。
Push 之后怎么办
场景:您执行了 push,之后才发现错误。
提交一旦进入服务器,就成为项目共享历史的一部分。试图通过 Reset 或 Amend 改写这段历史,可能会给同事带来很大麻烦 - 想想看,他们或许已经下载了您的更改,并基于这些更改开始了自己的工作。
正确且安全的做法:创建一个用于修复错误的新提交,然后像平常一样执行 push。这是很常见的做法。错误代码之后紧跟一个清晰的修复提交,这样的线性历史能让整个团队看清项目是如何演进的。
IDE 还提供了专门的 Revert Commit 功能。在 Git -> Log 日志中右键点击有问题的提交并选择 Revert Commit 后,IDE 会创建一个新的"反向提交",执行与原提交正好相反的操作(例如删除新增的行)。

当您需要用一个新提交撤销已经发布的更改时,Revert 很有用。它可以用于代码和文本,但可能与后续更改发生冲突。解决冲突后,请检查最终结果;如果依赖关系复杂,有时单独做一个修正会更清楚。
Stash / Shelve - 暂时收起更改
场景:您正在积极编写新功能,文件到处都是红色和蓝色。突然,组长赶来对您说:"先放下手头的事,赶紧修复 main 分支上的错误。"您没法切换到 main,因为还有未完成且互相冲突的更改。如果项目规则允许,可以先做一个临时的本地提交;但如果现在不方便提交,也可以把工作暂时搁置。
做法是先把工作临时放进一个虚拟盒子里。在 Git 中,这叫 Stash;IDE 还提供了单独的机制 Shelve(搁置到架上)。
- 打开
Commit窗口,选中已修改的文件; - 选择 Shelve Changes...;这些步骤针对的是 Shelve,Git Stash 需要单独调用;
- 为这条搁置记录起一个容易理解的名称,然后点击 Shelve。

执行 Shelve 后,检查剩下的文件,确认需要的更改都已搁置。现在可以切换到 main、修复错误,并按项目规则保存结果。然后回到工作分支,打开 Shelf 并选择 Unshelve。
使用 Git Stash 时,请在单独的 stash 列表中找到并恢复需要的记录。这是另一种存储方式。普通 stash 不会包含新建的 untracked 文件,除非使用额外选项;切换分支前,请确认需要的工作都已保存。恢复时可能发生冲突,之后也要再次检查文件。
查看日志的进阶用法
Git -> Log 窗口不只是提交列表,也是一个强大的调查工具。
- 提交哈希 是由字母和数字组成的字符串,例如
a1b2c3d。它是每个代码快照的唯一标识符。![日志中的提交哈希]()
- 可以按分支、作者、日期或提交说明中的词语筛选历史记录,快速找到谁在什么时候处理了某个部分;
- 要查找添加或删除某个特定代码行的提交,可以在
Log窗口中搜索提交说明,也可以搜索更改内容; - 在编辑器的行号区域右键点击,选择
Annotate with Git Blame,IDE 就会在每一行旁边显示最后修改它的人和提交。接着可以打开对应提交和相关讨论:Blame 只显示该行最后一次更改,不会说明原因。
危险操作 - Force Push
我们已经知道,改写推送过的提交不是好主意。但如果您确实修改了本地历史(例如使用 Undo Commit 或 Amend),而服务器上还是旧版本呢?普通的 push 会报错,以免共享历史被覆盖。
Force push 允许替换选定的远程引用,即使新历史并非从原历史延续而来。它不会清空整台服务器:后果取决于推送了哪些引用。分支保护也可能会阻止这次推送。
Force push 可能会从远程分支移除本地历史中没有的提交。因此,改写共享分支需要团队另行达成一致。普通修复请使用新提交或 Revert。
通常值得讨论 force push 的情形是:按约定改写了历史之后,推送您自己的分支。即使如此,也要确认没有其他人新推送的提交。--force-with-lease 会额外检查远程分支是否处于预期状态,但您仍然需要弄清哪些提交会被替换。
截图中,Force Push 位于 Push 按钮的下拉菜单里。使用前,请确认您的 IDE 版本采用哪种强制推送模式。

如果您不能百分之百确定自己在做什么,就不要使用 force push。创建一个修复用的新提交(或使用 Revert)更安全。
这条规则对您和 Claude Code 都一样:改写共享历史很危险。不要把 force push 当成常规做法,也不要让 Claude Code 在共享分支上执行它。如果 Claude 建议进行会改写服务器历史的操作,请先停下来,确认是否有安全的替代方案(例如新提交或 Revert)。
更新项目
开始新任务前,先检查基础分支和未完成的更改。需要时获取更新,并查看合并结果。Update Project 不保证不会发生冲突,具体可能根据设置使用 merge 或 rebase。
更新后,请检查当前分支、提交列表和文件状态。如果出现冲突,先处理完再继续任务。
Git Log 上下文菜单
打开 Git -> Log 标签页后,右键点击任意提交,就会出现一个很长的上下文菜单。我们按用途分组,看看其中最实用的命令。

第 1 组 - 查看与分析(安全操作)
Copy Revision Number会将提交的唯一哈希复制到剪贴板。您可以把它发给同事,或在任务中引用(Jira、YouTrack);Compare with Local会将旧提交中文件的状态与当前编辑器中的内容进行比较。很适合用来了解一个月前的代码是什么样;Show Repository at Revision会打开项目中所有文件在该提交时的目录结构(当前分支不会改变)。
第 2 组 - 分支操作
New Branch...会从过去选定的提交直接创建一个新分支。如果您已经向前走了很远,发现改坏了东西,并想从最近的正常状态另开分支,这个命令很有用;Checkout Revision会将本地项目切换到这个提交。此时您处于 分离头指针(detached HEAD) 状态:可以运行旧代码,但新提交不会归属于任何分支。如果在 detached HEAD 状态下创建了需要保留的提交,先用新分支保存它们。要返回,请 Checkout 一个普通分支(例如main)。
第 3 组 - 修改与移植
Cherry-Pick可以从另一个分支取出一个特定提交,并复制到当前分支。例如,同事在另一分支修复了一个阻碍您工作的错误,您可以 Cherry-Pick 这个提交,而不必合并整个分支;Edit Commit Message...如果提交还没有推送(尚未执行 Push),就可以快速修改它的说明。只需改文字时,它比 Amend 更方便。
第 4 组 - 撤销更改
上文已经详细介绍过这些命令:
Reset Current Branch to Here...会将当前分支移到此提交(从该分支可见的历史也会随之改变);Revert Commit会创建一个"反向提交",在新的本地提交中撤销已更改的内容,之后再推送到服务器;Undo Commit...会将本地提交拆回更改窗口。
第 5 组 - 改写历史
菜单中还有一些命令,例如 Squash Commits...(将多个提交合并为一个)、Drop Commits(从历史中间移除提交)或 Interactively Rebase from Here...。它们用于精细地整理本地历史(Interactive Rebase)。
熟悉这些操作期间,尽量不要使用这些命令,因为它们可能改写选定提交以及该分支后续的历史。在团队实际协作中,人们会在提交 Pull Request 供评审前,用它们整理本地的草稿分支。
Git 是您的安全网
根据任务当前所处的状态选择恢复方式:未提交的文件、本地提交和已发布的历史需要不同的操作。保留需要的版本,并在操作前查看更改,比寄希望于任何错误都能撤销要可靠得多。
与 Claude Code 配合使用
Claude Code 在项目中工作时,这些工具就是您的主要保护措施。可以这样使用:
- 经常创建提交:每个提交都是一个返回点。如果智能体走偏了,您可以回到最近的正常状态;
- 要撤销未提交的更改,先区分需要保留的内容,然后在 Rollback 或 git restore 中确认操作范围和恢复来源;
- 如果已经提交但尚未推送,
Undo Commit会把更改放回编辑器; - 如果错误已经在服务器上,创建修正用的新提交或使用
Revert,比改写历史更安全。
不要不加判断地同意删除数据或改写历史的操作(Reset hard、force push)。先查看 Claude Code 具体要做什么。开始大型任务前,请保存需要的状态,并确认返回点确实包含您的工作。
上一篇文章:Pull request:从创建到合并 · 下一篇文章:创建 repository、rebase 和秘密信息

GO TO FULL VERSION