跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Shell / Bash

Git 撤回已提交和已推送代码指南

Git 代码撤回的两种主要场景及解决方案。对于已提交未推送的代码,推荐使用 git reset 命令(如 --soft 保留更改),灵活撤销本地提交。对于已提交且已推送的代码,团队协作分支应使用 git revert 创建新提交以撤销变更,确保历史完整且安全;个人分支可谨慎使用 git reset 配合强制推送改写历史。操作前需备份,主分支禁止强制推送。掌握 reflog 可恢复误操作,遵循规范提交和分支保护策略能降低风险。

SqlMaster发布于 2026/3/28更新于 2026/10/24114 浏览

Git 代码撤回完全指南

在日常开发中,我们经常会遇到需要撤回代码的情况。本文将详细介绍两种常见场景的解决方案:已提交未推送的代码撤回,以及已提交已推送的代码撤回。

场景一:撤回已提交但未推送的代码

问题描述

代码已经通过 git commit 提交到本地仓库,但还没有 git push 到远程仓库。这时想要撤回这次提交。

解决方案
方案 1:保留代码更改(推荐)

使用 git reset --soft 可以撤销提交,但保留所有更改在暂存区:

# 撤销最近一次提交,保留更改在暂存区
git reset --soft HEAD~1 

效果:

  • ✅ 提交被撤销
  • ✅ 代码更改保留在暂存区(可以重新审查)
  • ✅ 可以重新修改后再次提交

查看当前状态:

git status 
方案 2:保留代码更改但取消暂存

使用 git reset --mixed(或简写为 git reset):

# 撤销最近一次提交,更改保留在工作区但不在暂存区
git reset HEAD~1 

效果:

  • ✅ 提交被撤销
  • ✅ 代码更改保留在工作区
  • ❌ 更改不在暂存区(需要重新 git add)
方案 3:完全删除代码更改(危险)

使用 git reset --hard,慎用:

# ⚠️ 警告:此操作会永久删除所有更改
git reset --hard HEAD~1 

效果:

  • ✅ 提交被撤销
  • ❌ 代码更改被永久删除
  • ⚠️ 无法恢复
撤销多次提交

如果要撤销最近 N 次提交:

# 撤销最近 3 次提交(保留更改)
git reset --soft HEAD~3 
# 撤销最近 2 次提交(删除更改)
git reset --hard HEAD~2 
后续操作
取消某个文件的暂存
git restore --staged <文件名>
# 取消所有文件的暂存
git restore --staged .
丢弃某个文件的更改
git restore <文件名>

场景二:撤回已提交且已推送的代码

问题描述

代码已经通过 git commit 提交并通过 推送到远程仓库。现在需要撤回这次提交。

git push
解决方案对比
方案安全性适用场景历史记录
git revert✅ 安全团队协作、主分支保留完整历史
git reset + force push⚠️ 危险个人分支改写历史

方案 1:git revert(推荐,安全)

原理: 创建一个新的提交来撤销之前的更改,不改变提交历史。

基本用法
# 撤销最近一次提交
git revert HEAD 
# 撤销指定的提交(使用提交哈希)
git revert <commit-hash>
# 自动使用默认提交信息(无需编辑器)
git revert HEAD --no-edit 
实战示例

1. 查看提交历史

git log --oneline -5 

输出示例:

963e69b Revert "前端报错问题" 88956dc Merge branch 'frontend' e9f4a9b 前端报错问题 e239e05 bug 修复 4c90d19 修改初始状态的布局 

2. 撤销指定提交

# 撤销 e9f4a9b 这个提交
git revert e9f4a9b --no-edit 

3. 推送到远程

git push 
处理工作区冲突

如果工作区有未提交的更改,revert 会失败:

错误信息 error: Your local changes would be overwritten by merge Please commit your changes or stash them before you merge. 

解决方法:暂存当前更改

# 1. 暂存当前更改
git stash 
# 2. 执行 revert
git revert <commit-hash> --no-edit 
# 3. 推送到远程
git push 
# 4. 恢复之前暂存的更改
git stash pop 
撤销多个连续提交
# 撤销从 commit1 到 commit3 的所有提交(不包含 commit1)
git revert commit1..commit3 
# 撤销多个不连续的提交
git revert commit1 commit2 commit3 
优点
  • ✅ 安全:不改变提交历史
  • ✅ 透明:团队成员可以看到完整的变更过程
  • ✅ 无冲突:不会影响其他人的本地仓库
  • ✅ 可追溯:保留了完整的操作记录

方案 2:git reset + 强制推送(谨慎使用)

原理: 直接回退到之前的提交并强制推送,改写远程历史。

基本用法
# 1. 回退到上一个提交
git reset --hard HEAD~1 
# 2. 强制推送到远程(⚠️ 危险操作)
git push --force 
回退到指定提交
# 查看提交历史
git log --oneline 
# 回退到指定提交
git reset --hard <commit-hash>
# 强制推送
git push --force 
使用 --force-with-lease(更安全)
# 更安全的强制推送,避免覆盖他人的提交
git push --force-with-lease 
⚠️ 警告与风险

严重后果:

  1. ❌ 历史被改写:提交记录被永久删除
  2. ❌ 团队冲突:其他成员拉取代码时会遇到冲突
  3. ❌ 数据丢失:如果操作不当可能永久丢失代码
  4. ❌ 信任问题:改写公共历史是不被推荐的做法

禁止场景:

  • ❌ 主分支(main/master):绝不使用 force push
  • ❌ 团队协作分支:其他人已经拉取过代码
  • ❌ 发布分支:已经部署到生产环境的代码

允许场景:

  • ✅ 个人特性分支:只有自己在使用
  • ✅ 本地测试分支:未被其他人拉取
  • ✅ 确认无人使用:明确知道没有其他人基于此开发

常见问题与注意事项

Q1: 如何选择使用哪种方案?

决策树:

代码是否已推送? ├─ 否 → 使用 git reset --soft HEAD~1 └─ 是 → 继续判断 ├─ 是否团队协作分支? │ ├─ 是 → 使用 git revert(必须) │ └─ 否 → 继续判断 │ └─ 其他人是否拉取过? │ ├─ 是 → 使用 git revert │ └─ 否 → 可以使用 git reset + force push 
Q2: git reset 的三种模式区别
模式命令提交历史暂存区工作区
softgit reset --soft HEAD~1撤销 ✓保留 ✓保留 ✓
mixedgit reset HEAD~1撤销 ✓清空 ✗保留 ✓
hardgit reset --hard HEAD~1撤销 ✓清空 ✗清空 ✗
Q3: 误操作后如何恢复?

如果不小心执行了 git reset --hard,可以使用 reflog 恢复:

# 查看所有操作历史
git reflog 
# 找到误操作前的提交哈希,然后恢复
git reset --hard <commit-hash>
Q4: 如何撤销 merge 提交?
# 如果是最近的 merge
git revert -m 1 HEAD 
# 如果是指定的 merge 提交
git revert -m 1<merge-commit-hash>
Q5: 团队成员已经拉取了错误代码怎么办?

使用 revert 后,团队成员只需:

git pull 

如果使用了 force push,团队成员需要:

# 1. 备份本地更改
git stash 
# 2. 强制同步远程(会丢失本地提交)
git fetch origin 
git reset --hard origin/<branch-name>
# 3. 恢复本地更改
git stash pop 

实战案例总结

案例 1:撤回未推送的提交

场景: 刚刚提交了一个不该提交的代码,但还未推送。

# 1. 撤回提交,保留更改
git reset --soft HEAD~1 
# 2. 查看状态
git status 
# 3. 取消不需要的文件暂存
git restore --staged <不需要的文件>
# 4. 重新提交需要的文件
git add <需要的文件>
git commit -m "正确的提交信息"
# 5. 推送
git push 
案例 2:撤回已推送的提交(团队协作)

场景: 推送了错误的代码到团队分支,需要撤回。

# 1. 暂存本地更改(如果有)
git stash 
# 2. 撤销指定提交
git log --oneline -5 
# 找到要撤销的提交哈希
git revert e9f4a9b --no-edit 
# 3. 推送
git push 
# 4. 恢复本地更改
git stash pop 
# 5. 通知团队成员
# 团队成员只需执行:git pull
案例 3:撤回个人分支的提交

场景: 在个人特性分支上推送了错误代码,确认无人使用。

# 1. 回退到上一个提交
git reset --hard HEAD~1 
# 2. 强制推送(确认是个人分支)
git push --force-with-lease 
# 注意:团队成员如果拉取过此分支会遇到冲突

最佳实践建议

1. 提交前检查
# 查看将要提交的更改
git diff --staged 
# 查看状态
git status 
2. 使用 Git 钩子

创建 .git/hooks/pre-commit 文件,在提交前自动检查:

#!/bin/sh
# 检查是否包含敏感信息
if git diff --cached | grep -i "password\|secret\|key"; then
    echo "⚠️ 检测到敏感信息,提交已阻止!"
    exit 1
fi
3. 分支保护策略
  • 主分支设置为受保护分支
  • 禁止直接推送到主分支
  • 必须通过 Pull Request 合并
  • 启用代码审查
4. 提交信息规范
# 使用规范的提交信息格式
git commit -m "feat: 添加用户登录功能"
git commit -m "fix: 修复实体详情报错问题"
git commit -m "refactor: 重构图表组件"

总结

场景推荐方案命令风险等级
已提交未推送git reset --softgit reset --soft HEAD~1🟢 低
已推送(团队)git revertgit revert <hash> --no-edit && git push🟢 低
已推送(个人)git reset + forcegit reset --hard HEAD~1 && git push --force🔴 高

核心原则:

  • ✅ 优先使用 git revert,安全可靠
  • ✅ 未推送时使用 git reset,灵活方便
  • ⚠️ 慎用 git push --force,确认无人使用
  • ❌ 永远不要在主分支使用 --force

参考资源

  • Git 官方文档
  • Git Reset 详解
  • Git Revert 详解

目录

  1. Git 代码撤回完全指南
  2. 场景一:撤回已提交但未推送的代码
  3. 问题描述
  4. 解决方案
  5. 方案 1:保留代码更改(推荐)
  6. 撤销最近一次提交,保留更改在暂存区
  7. 方案 2:保留代码更改但取消暂存
  8. 撤销最近一次提交,更改保留在工作区但不在暂存区
  9. 方案 3:完全删除代码更改(危险)
  10. ⚠️ 警告:此操作会永久删除所有更改
  11. 撤销多次提交
  12. 撤销最近 3 次提交(保留更改)
  13. 撤销最近 2 次提交(删除更改)
  14. 后续操作
  15. 取消某个文件的暂存
  16. 取消所有文件的暂存
  17. 丢弃某个文件的更改
  18. 场景二:撤回已提交且已推送的代码
  19. 问题描述
  20. 解决方案对比
  21. 方案 1:git revert(推荐,安全)
  22. 基本用法
  23. 撤销最近一次提交
  24. 撤销指定的提交(使用提交哈希)
  25. 自动使用默认提交信息(无需编辑器)
  26. 实战示例
  27. 撤销 e9f4a9b 这个提交
  28. 处理工作区冲突
  29. 1. 暂存当前更改
  30. 2. 执行 revert
  31. 3. 推送到远程
  32. 4. 恢复之前暂存的更改
  33. 撤销多个连续提交
  34. 撤销从 commit1 到 commit3 的所有提交(不包含 commit1)
  35. 撤销多个不连续的提交
  36. 优点
  37. 方案 2:git reset + 强制推送(谨慎使用)
  38. 基本用法
  39. 1. 回退到上一个提交
  40. 2. 强制推送到远程(⚠️ 危险操作)
  41. 回退到指定提交
  42. 查看提交历史
  43. 回退到指定提交
  44. 强制推送
  45. 使用 --force-with-lease(更安全)
  46. 更安全的强制推送,避免覆盖他人的提交
  47. ⚠️ 警告与风险
  48. 常见问题与注意事项
  49. Q1: 如何选择使用哪种方案?
  50. Q2: git reset 的三种模式区别
  51. Q3: 误操作后如何恢复?
  52. 查看所有操作历史
  53. 找到误操作前的提交哈希,然后恢复
  54. Q4: 如何撤销 merge 提交?
  55. 如果是最近的 merge
  56. 如果是指定的 merge 提交
  57. Q5: 团队成员已经拉取了错误代码怎么办?
  58. 1. 备份本地更改
  59. 2. 强制同步远程(会丢失本地提交)
  60. 3. 恢复本地更改
  61. 实战案例总结
  62. 案例 1:撤回未推送的提交
  63. 1. 撤回提交,保留更改
  64. 2. 查看状态
  65. 3. 取消不需要的文件暂存
  66. 4. 重新提交需要的文件
  67. 5. 推送
  68. 案例 2:撤回已推送的提交(团队协作)
  69. 1. 暂存本地更改(如果有)
  70. 2. 撤销指定提交
  71. 找到要撤销的提交哈希
  72. 3. 推送
  73. 4. 恢复本地更改
  74. 5. 通知团队成员
  75. 团队成员只需执行:git pull
  76. 案例 3:撤回个人分支的提交
  77. 1. 回退到上一个提交
  78. 2. 强制推送(确认是个人分支)
  79. 注意:团队成员如果拉取过此分支会遇到冲突
  80. 最佳实践建议
  81. 1. 提交前检查
  82. 查看将要提交的更改
  83. 查看状态
  84. 2. 使用 Git 钩子
  85. 检查是否包含敏感信息
  86. 3. 分支保护策略
  87. 4. 提交信息规范
  88. 使用规范的提交信息格式
  89. 总结
  90. 参考资源

更多推荐文章

查看全部
  • Qwen3-VL 模型架构及原理详解
  • 非计算机专业转行前端开发:自学路径与面试经验总结
  • AI 时代的架构设计:Vibe Coding 下的设计模式复兴
  • FPGA 商用级 ISP:动态坏点校正(DPCC)的滑窗架构与并行判决实现
  • AI 驱动下的内存市场变革:供需、能耗与安全趋势分析
  • LLM Agent 驱动 SLAM 回环检测:Python 与 LangChain 轻量化实践
  • AMD 显卡 llama.cpp 快速部署与兼容性解决方案
  • C++ 模板初阶:泛型编程核心解析
  • BERT 进阶指南:微调策略、模型变体与实战应用
  • TI 毫米波雷达自动 CLI 配置与控制代码操作方式
  • Mapnik 在 Windows 10 下的源码编译指南
  • 类加载器双亲委托机制详解
  • MCP 与 Skill 驱动的前端 JS 逆向自动化实践
  • 开源大模型争议:是真开源还是假开源?
  • 2024 开源图生视频模型横向评测:从 Stable Diffusion 到 SVD 的技术选型指南
  • LeetCode 链表专题:分割、相交及环形链表 C++ 解法
  • 分布式系统中如何确保 MQ 消息不丢失、重复消费及积压处理
  • 大模型应用开发:业务架构与技术路线解析(Embedded/Copilot/Agent)
  • 开源项目:全球情报监控平台 World Monitor
  • Flutter 三方库 arcane_helper_utils 鸿蒙化适配指南

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online