Git 撤销已提交远程仓库的推送
📝 前言
在使用 Git 时,常常会因为“手滑”把还没准备好的内容直接推送到远程仓库,或者推送完才发现问题 😅 。
虽然可以再补一个修正提交来“打补丁”,但这会在提交历史里留下尴尬的“黑历史”。
为了保持历史干净,自然会想:退回到某个合适的提交点,重新整理内容,再干干净净地推送一次 ✨。
下面就用一个简单示例,来演示如何安全地完成这个过程。
🧭 1. 查看当前历史,确认回退目标
git log --oneline -3
假设输出如下:
9a3a0ec (HEAD -> master, origin/master, origin/HEAD) Create 测试3.txt
2908bea Create 测试2.txt
8d8a615 Create 测试1.txt
- 想回退到
2908bea(上一个提交) → 可用2908bea或HEAD~1 - 想回退到
8d8a615(再上一个提交) → 可用8d8a615或HEAD~2
💡 小技巧:
HEAD~n表示当前提交往前数第 n 个提交,非常方便!
⏪ 2. 在本地执行回退
使用 git reset 有三种模式,效果不同,按需选择 👇:
📌 使用相对引用(以回退到 2908bea 为例)
git reset --soft HEAD~1 # 回到 2908bea,9a3a0ec 的改动保留在暂存区(已 add,未 commit)
git reset --mixed HEAD~1 # 回到 2908bea,9a3a0ec 的改动变成“未暂存的修改”(已修改,未 add)
git reset --hard HEAD~1 # 回到 2908bea,9a3a0ec 的改动彻底丢弃 ⚠️(危险操作!)
📌 使用具体提交哈希(与上面效果完全相同)
git reset --soft 2908bea
git reset --mixed 2908bea
git reset --hard 2908bea
💡 如何选择?
- 若想重新修改提交信息或补文件后再提交 →
--soft- 若想重新选择哪些文件要提交(重新 add)→
--mixed- 若这些改动完全没用了 →
--hard🗑️
🚀 3. 强制推送到远程
现在你的本地仓库已经“倒退”了(假设远程还停在 9a3a0ec),普通 git push 会被拒绝。
你需要明确告诉 Git:“我就是要用本地覆盖远程!” 🌊
务必使用更安全的强制推送命令:
git push --force-with-lease
✅ 这个命令会先检查远程分支是否还是你上次拉取时的状态,如果没有其他人在此期间推送了新内容,才允许覆盖。
这样就可以避免误伤队友的提交,比 git push -f 安全太多 👍。
如果这是你个人独享的分支,而且你完全确定没有其他人改动,也可以使用 git push -f,但推荐把 --force-with-lease 培养成肌肉记忆 💪。
🔍 4. 验证远程是否已更新
git log --oneline -3
确认远程分支的顶端已经是你的目标提交,一切就大功告成啦 🎉。