Git撤回已经提交(甚至已push)的代码,但把改动留在本地的解决

Written by

in

文章目录
  • 如果你只是: 刚 push 想撤回最近一次提交 代码还要留着 直接用这两步就够了: git reset HEAD~1 git push –force-with-lease origin main 执行完: 远端没有这次提交 本地 git log 也没有 代码还在(变成未提交状态) 很多时候,到这一步就结束了。
  • 有些人不太喜欢这种“当前分支推上去”的方式,更希望明确写: 👉 我要回到哪个提交 那可以用 commit id。
  • 最简单: git log –oneline 比如看到: 070505c github page ← 这个是你想撤回的 ff775f6 first commit ← 这个是你要回退到的 👉 记住:你要的是前一个“正确提交”的 id 如果想看得更清楚一点: git log –oneline –graph –decorate -5
  • git reset –mixed ff775f6 效果: 提交记录回退 代码还在 不在暂存区 如果你希望改动还在暂存区: git reset –soft ff775f6
  • git push –force-with-lease origin ff775f6:main 这句的意思很直白: 👉 把远端 main 指向 ff775f6
  • GitHub 上看不到那次错误提交 本地历史也没有 代码还在你本地,可以继续改 这就是很多人想要的“撤回但保留代码”。
  • 你可能见过这种写法: git reset –hard <commit> git push –force-with-lease origin <commit>:main git cherry-pick –no-commit <某个提交> 这套其实是补救方案,不是常规操作。 它通常用于: 你已经 reset –hard 把代码清掉了 或者你想只恢复某一次提交的内容 正常情况下(尤其是刚提交就反悔),用不到这么重。
  • 很多教程会说用: git revert 但它做的事情是: 新增一个“反向提交” 也就是说: 原来的错误提交还在 只是多了一次“撤销它”的提交 如果你的目标是: 👉 让这次提交彻底从历史里消失 那就不要用 revert。
  • 有,而且必须说清楚。 因为你用了: git push –force-with-lease 这叫改写历史。
  • 几个简单建议:
  • 如果你只是: 👉 “刚 push,想撤回,但代码要留着” 记这一套就够了: git reset HEAD~1 git push –force-with-lease origin main 如果你想完全可控(明确回到哪个点): git log –oneline git reset –mixed <commit-id> git push –force-with-lease origin <commit-id>:main
  • 这件事本质其实就一句话:  删的是提交记录,不是代码内容。 理解这一点,Git 基本就通了。 以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。 您可能感兴趣的文章: Git撤回已Push的代码的方法大全 在Git中撤回最近的commit的多种方式小结 Git撤回合并提交的多种方法 idea中实用的git操作问题小结(撤回commit,撤回push、暂存区使用) IDEA中git撤回上一次push的方法(指定回到某个版本)
  • 目录
    • 先说人话版结论
    • 这两条命令到底干了啥
      • 第一条
      • 第二条
    • 如果你更想“精确控制”,可以指定 commit id
      • 第一步:查 commit id
        • 第二步:本地回退到这个 id
          • 第三步:远端也强制回退
            • 到这里为止,你得到什么
              • 那什么时候要用“三段式写法”?
                • 为什么不推荐用 git revert
                  • 一个很现实的问题:这操作有风险吗?
                    • 风险 1:可能覆盖别人的提交
                    • 风险 2:别人本地会“乱掉”
                  • 怎么尽量安全一点
                    • 1. 尽量别在多人共用分支乱搞
                    • 2. 一定用这个
                    • 3. 操作前看一眼远端
                    • 4. 如果已经被别人用了,别改历史
                  • 最后给你一个记忆版本
                    • 总结一下

                      这个坑基本每个人都会踩一遍:

                      刚 commit 完,顺手 push 了。

                      过了两分钟发现:这提交现在不该上去

                      但问题是——

                      代码你还要留着,得继续改,而不是直接删掉。

                      这篇就讲一件事:

                      怎么把提交从历史里“抹掉”,但代码还留在本地

                      公共提交避免使用这个方法,如果你是独立开发,那没问题!!!

                      如果你只是:

                      • 刚 push
                      • 想撤回最近一次提交
                      • 代码还要留着

                      直接用这两步就够了:

                      git reset HEAD~1
                      git push --force-with-lease origin main

                      执行完:

                      • 远端没有这次提交
                      • 本地 git log 也没有
                      • 代码还在(变成未提交状态)

                      很多时候,到这一步就结束了。

                      git reset HEAD~1

                      意思是:

                      把当前分支往前退一个提交

                      但注意,它不会删你的代码,只是把:

                      • commit 里的内容
                      • 👉 变回工作区改动

                      所以你会看到:

                      • 文件还在
                      • 只是变成“未提交”

                      git push --force-with-lease origin main

                      意思是:

                      用你当前本地的 main,覆盖远端 main

                      也就是把刚才“回退后的状态”同步到远端。

                      有些人不太喜欢这种“当前分支推上去”的方式,更希望明确写:

                      👉 我要回到哪个提交

                      那可以用 commit id。

                      最简单:

                      git log --oneline

                      比如看到:

                      070505c github page   ← 这个是你想撤回的
                      ff775f6 first commit  ← 这个是你要回退到的

                      👉 记住:你要的是前一个“正确提交”的 id

                      如果想看得更清楚一点:

                      git log --oneline --graph --decorate -5

                      git reset --mixed ff775f6

                      效果:

                      • 提交记录回退
                      • 代码还在
                      • 不在暂存区

                      如果你希望改动还在暂存区:

                      git reset --soft ff775f6

                      git push --force-with-lease origin ff775f6:main

                      这句的意思很直白:

                      👉 把远端 main 指向 ff775f6

                      • GitHub 上看不到那次错误提交
                      • 本地历史也没有
                      • 代码还在你本地,可以继续改

                      这就是很多人想要的“撤回但保留代码”。

                      你可能见过这种写法:

                      git reset --hard <commit>
                      git push --force-with-lease origin <commit>:main
                      git cherry-pick --no-commit <某个提交>

                      这套其实是补救方案,不是常规操作。

                      它通常用于:

                      • 你已经 reset --hard 把代码清掉了
                      • 或者你想只恢复某一次提交的内容

                      正常情况下(尤其是刚提交就反悔),用不到这么重。

                      很多教程会说用:

                      git revert
                      

                      但它做的事情是:

                      新增一个“反向提交”

                      也就是说:

                      • 原来的错误提交还在
                      • 只是多了一次“撤销它”的提交

                      如果你的目标是:

                      👉 让这次提交彻底从历史里消失

                      那就不要用 revert

                      有,而且必须说清楚。

                      因为你用了:

                      git push --force-with-lease

                      这叫改写历史

                      如果你 push 之前:

                      👉 别人已经往 main 提交了新代码

                      那你这一推,有可能把对方的提交顶掉。

                      你改了远端历史之后:

                      • 别人本地还是旧历史
                      • pull / push 可能冲突
                      • 甚至把你删掉的提交再带回来

                      几个简单建议:

                      尤其是 main 正在被多人提交的时候。

                      git push --force-with-lease

                      而不是:

                      git push --force

                      前者至少会帮你检查远端有没有被别人改过。

                      git fetch origin
                      git log --oneline --graph --decorate --all -10

                      这种时候更建议:

                      git revert

                      如果你只是:

                      👉 “刚 push,想撤回,但代码要留着”

                      记这一套就够了:

                      git reset HEAD~1
                      git push --force-with-lease origin main

                      如果你想完全可控(明确回到哪个点):

                      git log --oneline
                      git reset --mixed <commit-id>
                      git push --force-with-lease origin <commit-id>:main

                      这件事本质其实就一句话:

                       删的是提交记录,不是代码内容。

                      理解这一点,Git 基本就通了。

                      以上为个人经验,希望能给大家一个参考,也希望大家多多支持风君子博客。

                      您可能感兴趣的文章:

                      • Git撤回已Push的代码的方法大全
                      • 在Git中撤回最近的commit的多种方式小结
                      • Git撤回合并提交的多种方法
                      • idea中实用的git操作问题小结(撤回commit,撤回push、暂存区使用)
                      • IDEA中git撤回上一次push的方法(指定回到某个版本)

                      站内搜索