如果您参与过团队编程项目,就会知道一旦尝试撤销更改,事情可能会很快失控。一步走错,轻则抹掉自己的工作,重则破坏队友刚推送的内容。
这就是为什么了解 Git 提供的“撤销”机制以及各自适用场景如此重要。有些命令适合团队环境,而另一些更适合 本地 清理,在这种情况下您可以放心地重写历史。
本指南将带您逐步了解。您将学到撤销提交的不同方法、其工作原理,以及在不同情境下应当选择哪一种。
理解 Git 提交历史
有没有按过“Ctrl+S”保存文档版本,之后再回到那个版本?Git 的一次提交做的正是类似的事,但作用于整个代码库。
Git 中的提交是什么?
一次 git commit 是您项目的某一时刻快照。它冻结当前所有文件的状态,并为该版本分配唯一 ID,就像给代码拍了一张带时间戳的照片。若之后出现问题,您随时可以回到那个时间点。
它如何工作?当您修改仓库中的文件时,更改并不会立即保存。它们先仅存在于本地的工作目录中。要保存这些更改,您需要先暂存(stage),再提交到仓库。提交历史就是对该仓库执行的所有提交的日志。
本地提交 vs 远程提交
本地提交保留在您的机器上,直到您决定共享之前同事或协作者都看不到。这意味着您对此有更多掌控:您可以重写历史、压缩、删除或重置,而不影响他人。
另一方面,远程提交对所有在该仓库上工作的人可见。这意味着您不应重写或删除这些提交。如果这么做,而队友正在使用同一远程分支,就会给他们造成破坏。因此在重写共享历史之前,您应格外谨慎并明确自己在做什么。
在本地撤销上一次 Git 提交
在 Git 中,HEAD 指向项目历史中的最新一次提交。使用 git reset 命令时,您就是在让 Git 将该指针移到另一个提交上。
下面我们拆解如何使用 git reset 在不同场景中撤销上一次提交。
使用 git reset --soft HEAD~1
它会将 HEAD 回退一个提交,但保留更改在暂存区。您的文件不会被动到,所有提交过的内容仍然排队等待在暂存区。适用于只想撤销提交本身,但保留所有更改且保持已暂存的情况。
使用 git reset --mixed HEAD~1
这一步走得更远。它同样将 HEAD 回退一个提交,但会清空暂存区。您的文件仍在工作目录中,但没有任何内容处于已暂存状态。这是 git reset 的默认模式。
使用 git reset --head HEAD~1
它会回退 HEAD、清空暂存区,并清除工作目录中的更改。就像上一次提交(及其所有更改)从未存在过。
谨慎使用——一旦这些更改被抹掉,就很难找回。因此,只有当您完全确定不需要上一次提交的任何内容时再运行它。
示例 1:在本地撤销上一次提交(安全返工)
假设您刚刚完成一次提交,却发现忘了更新 README 文件。
情境:
您已提交了对 main.py 的更改,但忘记更新 README.md。您想修订上一次提交而不影响他人,且尚未推送任何内容。
解决方案:
使用 git reset --soft HEAD~1 撤销提交并保留更改在暂存区:
git reset --soft HEAD~1技术支持
现在,更新 README 文件,将其加入暂存并重新提交所有内容:
git add README.md
git commit -m "Update main.py and README.md"技术支持
✅ 原理:由于该提交尚未推送,您可以重写本地历史而不会影响任何人。
撤销已推送的 Git 提交
您已经推送了一次提交……然后开始后悔。谁都会遇到这种情况。但如何在不破坏团队成员工作的情况下撤销它呢?
使用 git push --force 重写历史
通常,只有当您的本地分支刚刚拉取并与远程分支保持最新时,Git 才允许您推送。但您可以通过像 push --force 这样的“超能力”命令绕过这一规则。它会用本地分支的内容覆盖远程的整个历史。
这就是为什么 --force 功能强大却危险。在团队环境中,如果您尚未将同事的提交拉取到本地分支,它可能会删除他们的提交。只有在完全清楚后果时才使用它——理想情况下,只在您独自维护该仓库时使用。
除了 push --force,还有 pull --force,同样是需要谨慎使用的强力命令。了解更多内容请见 这里。
使用 git revert 的更安全替代方案
如果您想撤销提交但不删除历史,git revert 是最佳选择。它不会移除提交;而是创建一个新的提交来抵消这些更改。
比如,您提交了一个名为 streamlit_app.py 的文件,现在想去掉它。git revert 会生成一个新的提交,仅删除这个文件,同时保持其余历史不变。
默认情况下,git revert 作用于最近的一次提交。不过,您也可以通过指定提交 ID 来回退更早的提交。
示例 2:在共享分支上安全撤销已推送的提交
假设您推送了一个错误的配置更改,需要在不删除历史的情况下将其回退。
情境:
您推送了一次向 config.yaml 添加错误行的提交。团队已经在同一远程分支(main)上工作,因此您不能使用 reset 或强制推送。
解决方案:
使用 git revert 安全地撤销该提交:
git revert <commit-hash>技术支持
这会打开一个文本编辑器让您确认回退信息。保存并关闭编辑器后,将创建一个新的提交来撤销先前的提交。
如果要回退的是最后一次提交:
git revert HEAD技术支持
然后推送更改:
git push origin main技术支持
✅ 原理:git revert 不会重写历史——它会新增一个提交。因此对共享分支和团队协作流程来说是安全的。
可视化与确认更改
有时,您只是想看看目前发生了什么——有点像回滚到之前的版本,找到想要撤销的那次提交。Git 提供了相应工具来实现这一点。
使用 git log 检查提交历史
在终端中运行 git log,您会看到当前分支上的所有提交列表。您可以借此定位需要撤销或修改的特定提交。
例如:git log 的输出可能如下:
- e3a1b7f 修复 README 中的拼写错误
- 4f2c9a1 添加登录校验
- 9d5b3e8 初始化提交
每一行都会显示提交哈希和消息。如果想撤销某个特定更改,只需复制该提交哈希并配合 git revert 使用即可。
使用图形化工具或扩展
如果您不是开发者或没用过版本控制,这些命令行指令可能像外语一样晦涩。这时图形化工具就派上用场了。它们让 Git 变得可视化且对新手友好,您无需死记硬背命令即可专注于核心工作。
GitHub Desktop
GitHub Desktop 是一款免费的应用,为您提供简洁易用的界面来操作 GitHub 仓库。安装后,您可以用它创建分支、进行提交、推送到远程并管理项目,全部通过点击而非 Git 命令 完成。
如果您是 Git 新手,或只是想更顺畅地管理更改,它再合适不过。

GitHub Desktop 用户界面。图片来源。
Sourcetree
Sourcetree 是一款免费的 Git 图形化工具,支持 Mac 和 Windows。它为管理分支、提交与合并提供可视化方式,无需接触终端。它轻量、对初学者友好,并能很好地与 GitHub、GitLab、Bitbucket 等常用平台协作。
由于由 Atlassian 开发,它也能与 Jira、Confluence、Bamboo 等 Atlassian 工具良好集成,如果您的团队已在使用该生态,这是不错的选择。

Sourcetree 用户界面。图片来源。
GitKraken
GitKraken 是一款功能丰富的 Git 图形化工具,让使用仓库变得顺滑而直观。它的亮点是图谱视图——五彩交互的时间线,清晰展示仓库历史中的分支、合并与提交。
左侧是项目的文件树,右侧是您点击的提交、文件或分支的详细信息。它直观、对新手友好,同时也为高级用户提供强大功能。
GitKraken 对个人使用免费,但如果您在企业环境中或管理私有仓库,则需要付费计划。

Gitkraken 用户界面。图片来源。
撤销 Git 提交的最佳实践
只要遵循良好实践,撤销提交并不可怕。我们来谈谈有哪些做法。
用分支进行试验
每当您要构建新功能或修复缺陷时,从 main 上创建一个单独的分支。在那上面完成全部工作,充分测试后,再把它合并回主分支。
这样一来,任何错误或回滚都安全地局限在您的分支中,不会妨碍团队其他人的工作。
拿不准时,用 git revert
假设您在本地分支上做了几次提交,却不小心推送到了主分支。糟糕。现在您想撤销其中一次提交,又不想搞乱共享历史。这就是 git revert 派上用场的时候。
运行 git revert HEAD~1。这会创建一个新提交,撤销倒数第二次提交的更改(因为 HEAD~1 指向它)。它不会删除任何东西,而是以干净、可追踪的方式反向应用更改。
完成后,别忘了使用 git push origin <your-branch-name> 将修复推送到远程。
注意:如果更改已经推送到共享分支,请使用 git revert。它会保持提交历史完整,不会干扰队友。
记录您的更改
您不需要专门写一页 Confluence 来维护版本历史,因为 Git 已经帮您做了。诀窍是聪明地使用它。
从清晰、有意义的提交消息开始。如果您在回退某些内容,请确保消息解释了为什么要这么做。
并记录下提交 ID 和变更摘要。通常这就足以满足文档记录的需求。
团队协作
当您在他人也在使用的分支上运行 git reset、rebase 或 commit --amend 等命令时,您在更改提交历史。任何已拉取旧历史的人现在都会面临冲突。
因此,只在本地或功能分支上使用重写历史的命令。如果必须强制推送或重写共享历史,请尽早与团队沟通。
结论
Git 提供了多种方式来撤销错误;但知道何时、如何使用每种工具,正是自信开发者与迷茫开发者的分水岭。
我们探讨了 git reset 在不同模式下的工作方式、何时使用 git revert,以及为何必须根据具体情境选择合适工具。
总结如下:
- 在推送到共享分支后避免重写历史
- 若必须强制推送,请尽早沟通
- 使用
git revert 安全地撤销已推送的提交
接下来,了解您可以如何在此处回退合并提交。如果您已经掌握基础并准备更进一步,欢迎查看我们的 Git 进阶课程!
如果您参与过团队编程项目,就会知道一旦尝试撤销更改,事情可能会很快失控。一步走错,轻则抹掉自己的工作,重则破坏队友刚推送的内容。
这就是为什么了解 Git 提供的“撤销”机制以及各自适用场景如此重要。有些命令适合团队环境,而另一些更适合 本地 清理,在这种情况下您可以放心地重写历史。
本指南将带您逐步了解。您将学到撤销提交的不同方法、其工作原理,以及在不同情境下应当选择哪一种。
理解 Git 提交历史
有没有按过“Ctrl+S”保存文档版本,之后再回到那个版本?Git 的一次提交做的正是类似的事,但作用于整个代码库。
Git 中的提交是什么?
一次 git commit 是您项目的某一时刻快照。它冻结当前所有文件的状态,并为该版本分配唯一 ID,就像给代码拍了一张带时间戳的照片。若之后出现问题,您随时可以回到那个时间点。
它如何工作?当您修改仓库中的文件时,更改并不会立即保存。它们先仅存在于本地的工作目录中。要保存这些更改,您需要先暂存(stage),再提交到仓库。提交历史就是对该仓库执行的所有提交的日志。
本地提交 vs 远程提交
本地提交保留在您的机器上,直到您决定共享之前同事或协作者都看不到。这意味着您对此有更多掌控:您可以重写历史、压缩、删除或重置,而不影响他人。
另一方面,远程提交对所有在该仓库上工作的人可见。这意味着您不应重写或删除这些提交。如果这么做,而队友正在使用同一远程分支,就会给他们造成破坏。因此在重写共享历史之前,您应格外谨慎并明确自己在做什么。
在本地撤销上一次 Git 提交
在 Git 中,HEAD 指向项目历史中的最新一次提交。使用
git reset命令时,您就是在让 Git 将该指针移到另一个提交上。下面我们拆解如何使用
git reset在不同场景中撤销上一次提交。使用 git reset --soft HEAD~1
它会将 HEAD 回退一个提交,但保留更改在暂存区。您的文件不会被动到,所有提交过的内容仍然排队等待在暂存区。适用于只想撤销提交本身,但保留所有更改且保持已暂存的情况。
使用 git reset --mixed HEAD~1
这一步走得更远。它同样将 HEAD 回退一个提交,但会清空暂存区。您的文件仍在工作目录中,但没有任何内容处于已暂存状态。这是
git reset的默认模式。使用 git reset --head HEAD~1
它会回退 HEAD、清空暂存区,并清除工作目录中的更改。就像上一次提交(及其所有更改)从未存在过。
谨慎使用——一旦这些更改被抹掉,就很难找回。因此,只有当您完全确定不需要上一次提交的任何内容时再运行它。
示例 1:在本地撤销上一次提交(安全返工)
假设您刚刚完成一次提交,却发现忘了更新 README 文件。
情境:
您已提交了对
main.py的更改,但忘记更新README.md。您想修订上一次提交而不影响他人,且尚未推送任何内容。解决方案:
使用
git reset --soft HEAD~1撤销提交并保留更改在暂存区:现在,更新 README 文件,将其加入暂存并重新提交所有内容:
✅ 原理:由于该提交尚未推送,您可以重写本地历史而不会影响任何人。
撤销已推送的 Git 提交
您已经推送了一次提交……然后开始后悔。谁都会遇到这种情况。但如何在不破坏团队成员工作的情况下撤销它呢?
使用 git push --force 重写历史
通常,只有当您的本地分支刚刚拉取并与远程分支保持最新时,Git 才允许您推送。但您可以通过像
push --force这样的“超能力”命令绕过这一规则。它会用本地分支的内容覆盖远程的整个历史。这就是为什么
--force功能强大却危险。在团队环境中,如果您尚未将同事的提交拉取到本地分支,它可能会删除他们的提交。只有在完全清楚后果时才使用它——理想情况下,只在您独自维护该仓库时使用。除了
push --force,还有pull --force,同样是需要谨慎使用的强力命令。了解更多内容请见 这里。使用 git revert 的更安全替代方案
如果您想撤销提交但不删除历史,
git revert是最佳选择。它不会移除提交;而是创建一个新的提交来抵消这些更改。比如,您提交了一个名为
streamlit_app.py的文件,现在想去掉它。git revert会生成一个新的提交,仅删除这个文件,同时保持其余历史不变。默认情况下,
git revert作用于最近的一次提交。不过,您也可以通过指定提交 ID 来回退更早的提交。示例 2:在共享分支上安全撤销已推送的提交
假设您推送了一个错误的配置更改,需要在不删除历史的情况下将其回退。
情境:
您推送了一次向
config.yaml添加错误行的提交。团队已经在同一远程分支(main)上工作,因此您不能使用reset或强制推送。解决方案:
使用
git revert安全地撤销该提交:这会打开一个文本编辑器让您确认回退信息。保存并关闭编辑器后,将创建一个新的提交来撤销先前的提交。
如果要回退的是最后一次提交:
然后推送更改:
✅ 原理:
git revert不会重写历史——它会新增一个提交。因此对共享分支和团队协作流程来说是安全的。可视化与确认更改
有时,您只是想看看目前发生了什么——有点像回滚到之前的版本,找到想要撤销的那次提交。Git 提供了相应工具来实现这一点。
使用 git log 检查提交历史
在终端中运行
git log,您会看到当前分支上的所有提交列表。您可以借此定位需要撤销或修改的特定提交。例如:
git log的输出可能如下:每一行都会显示提交哈希和消息。如果想撤销某个特定更改,只需复制该提交哈希并配合
git revert使用即可。使用图形化工具或扩展
如果您不是开发者或没用过版本控制,这些命令行指令可能像外语一样晦涩。这时图形化工具就派上用场了。它们让 Git 变得可视化且对新手友好,您无需死记硬背命令即可专注于核心工作。
GitHub Desktop
GitHub Desktop 是一款免费的应用,为您提供简洁易用的界面来操作 GitHub 仓库。安装后,您可以用它创建分支、进行提交、推送到远程并管理项目,全部通过点击而非 Git 命令 完成。
如果您是 Git 新手,或只是想更顺畅地管理更改,它再合适不过。
GitHub Desktop 用户界面。图片来源。
Sourcetree
Sourcetree 是一款免费的 Git 图形化工具,支持 Mac 和 Windows。它为管理分支、提交与合并提供可视化方式,无需接触终端。它轻量、对初学者友好,并能很好地与 GitHub、GitLab、Bitbucket 等常用平台协作。
由于由 Atlassian 开发,它也能与 Jira、Confluence、Bamboo 等 Atlassian 工具良好集成,如果您的团队已在使用该生态,这是不错的选择。
Sourcetree 用户界面。图片来源。
GitKraken
GitKraken 是一款功能丰富的 Git 图形化工具,让使用仓库变得顺滑而直观。它的亮点是图谱视图——五彩交互的时间线,清晰展示仓库历史中的分支、合并与提交。
左侧是项目的文件树,右侧是您点击的提交、文件或分支的详细信息。它直观、对新手友好,同时也为高级用户提供强大功能。
GitKraken 对个人使用免费,但如果您在企业环境中或管理私有仓库,则需要付费计划。
Gitkraken 用户界面。图片来源。
撤销 Git 提交的最佳实践
只要遵循良好实践,撤销提交并不可怕。我们来谈谈有哪些做法。
用分支进行试验
每当您要构建新功能或修复缺陷时,从 main 上创建一个单独的分支。在那上面完成全部工作,充分测试后,再把它合并回主分支。
这样一来,任何错误或回滚都安全地局限在您的分支中,不会妨碍团队其他人的工作。
拿不准时,用 git revert
假设您在本地分支上做了几次提交,却不小心推送到了主分支。糟糕。现在您想撤销其中一次提交,又不想搞乱共享历史。这就是
git revert派上用场的时候。运行
git revert HEAD~1。这会创建一个新提交,撤销倒数第二次提交的更改(因为 HEAD~1 指向它)。它不会删除任何东西,而是以干净、可追踪的方式反向应用更改。完成后,别忘了使用
git push origin <your-branch-name>将修复推送到远程。注意:如果更改已经推送到共享分支,请使用
git revert。它会保持提交历史完整,不会干扰队友。记录您的更改
您不需要专门写一页 Confluence 来维护版本历史,因为 Git 已经帮您做了。诀窍是聪明地使用它。
从清晰、有意义的提交消息开始。如果您在回退某些内容,请确保消息解释了为什么要这么做。
并记录下提交 ID 和变更摘要。通常这就足以满足文档记录的需求。
团队协作
当您在他人也在使用的分支上运行
git reset、rebase或commit --amend等命令时,您在更改提交历史。任何已拉取旧历史的人现在都会面临冲突。因此,只在本地或功能分支上使用重写历史的命令。如果必须强制推送或重写共享历史,请尽早与团队沟通。
结论
Git 提供了多种方式来撤销错误;但知道何时、如何使用每种工具,正是自信开发者与迷茫开发者的分水岭。
我们探讨了
git reset在不同模式下的工作方式、何时使用git revert,以及为何必须根据具体情境选择合适工具。总结如下:
git revert安全地撤销已推送的提交接下来,了解您可以如何在此处回退合并提交。如果您已经掌握基础并准备更进一步,欢迎查看我们的 Git 进阶课程!