【问题标题】:How to revert last commit and remove it from history?如何恢复上次提交并将其从历史记录中删除?
【发布时间】:2012-02-12 19:22:48
【问题描述】:

我做了一个提交并用

还原
git revert HEAD^

只需 git 日志

➜  git:(master) git log
commit 45a0b1371e4705c4f875141232d7a97351f0ed8b
Author: Daniel Palacio <danpal@gmail.com>
Date:   Tue Jan 17 16:32:15 2012 -0800

    Production explanation

但如果我执行 git log --all 它仍然会显示。我需要将其从历史记录中删除,因为它包含敏感信息

git log --all
commit 5d44355080500ee6518f157c084f519da47b9391
Author: Daniel Palacio
Date:   Tue Jan 17 16:40:48 2012 -0800

    This commit has to be reset

commit 45a0b1371e4705c4f875141232d7a97351f0ed8b
Author: Daniel Palacio 
Date:   Tue Jan 17 16:32:15 2012 -0800

    Production explanation

如何也从历史记录中删除提交 5d44355080500ee6518f157c084f519da47b9391?

【问题讨论】:

  • Git undo last commit的可能重复
  • @AdrianCornish:这是一个好的开始,但它对“敏感信息”位没有帮助。
  • @KevinBallard - 一个 git reset --hard 会吗?假设它没有被推到任何地方 - 如果它被推,所有赌注都关闭
  • @AdrianCornish:是的,但前提是他可以接受保留在本地副本中的敏感信息。他应该是,但我不能为他说话。
  • 数据库清理后为什么硬重置会留下数据?

标签: git git-revert


【解决方案1】:

这是一个简单的工作解决方案,可以从远程删除最后一次提交:

  1. 克隆 repo 并找到最后一个“好的”提交 (....c407)
$ git clone git@host:PROJ/myrepo.git 
$ cd myrepo 
$ git log --pretty=oneline

234987fed789de97232ababababcef3234958723 bad_commit
e4a2ec4a80ef63e1e2e694051d9eb3951b14c407 v4.3
2f116449144dbe46e7260d5dac2304803751b5c2 v4.2
  1. 签出对新临时分支的最后一次良好提交
$ git checkout e4a2ec4a80ef63e1e2e694051d9eb3951b14c407
$ git checkout -b temp_branch
  1. 替换远程分支(删除并推送临时)
git push origin --delete dev_branch
git push origin temp_branch:dev_branch

【讨论】:

    【解决方案2】:

    有一个很好的解决方案here。 要删除最后一个(顶部)提交,您可以这样做

    git push [remote] +[bad_commit]^:[branch]
    

    其中 [bad_commit] 是 [branch] 当前指向的提交,或者如果 [branch] 在本地签出,也可以这样做

    git reset HEAD^ --hard
    git push [remote] -f
    

    【讨论】:

      【解决方案3】:

      如果您不关心提交,请执行以下操作:

      git reset --hard HEAD~
      

      吹走提交。

      如果您希望更改位于工作目录中,请执行以下操作:

      git reset HEAD~
      

      根据您对git revert 所做的操作,您可能需要更改上述命令。 Revert 创建一个新的提交,该提交会还原您想要还原的提交。所以会有两个提交。您可能需要执行 HEAD~2 才能将它们都删除。

      请注意,通常,还原是还原更改的更安全的方法。但是在这里,由于您要删除敏感数据,因此重置是最好的方法。

      【讨论】:

        【解决方案4】:

        如果你还没有推送提交,你可以:

        git reset --hard HEAD~2

        (HEAD~2 删除您的原始提交和“恢复”提交)。

        这会将您当前的分支重置到您要删除的提交之前的历史记录点。如果该提交不在任何其他分支中,则不会将其推送到您的来源。

        【讨论】:

        • 这对历史部分没有帮助。该提交仍在历史记录中。
        • 并非如此,从此时起,该提交将不再是您当前分支的一部分,最终将被 git gc 删除。如果你现在想真正删除提交,你可以使用 git gc 现在修剪它,或者再次克隆存储库;克隆存储库时,仅克隆某个分支可访问的提交。
        【解决方案5】:

        首先,git revert 在这里是错误的命令。这会创建一个新的提交来恢复旧的提交。这不是你要的。其次,您似乎想恢复 HEAD 而不是 HEAD^

        如果您没有将其推送到任何地方,您可以使用git reset --hard HEAD^ 丢弃最新的提交(这也会丢弃所有未提交的更改,因此请确保您没有任何要保存的内容)。假设您对您的副本中存在的敏感信息感到满意,而没有其他人的,那么您就完成了。您可以继续工作,后续的 git push 不会推送您的错误提交。

        如果这不是一个安全的假设(尽管如果不是,我很想听听为什么),那么您需要使您的 reflogs 过期并强制进行垃圾回收,以立即收集所有未完成的对象。你可以这样做

        git reflog expire --expire=now --expire-unreachable=now --all
        git gc --prune=now
        

        尽管只有当你真的绝对需要时才应该这样做。


        如果你推送了你的提交,那么你就很不走运了。您可以执行强制推送以远程恢复它(尽管只有在远程端允许的情况下),但您不能从远程端的数据库中删除提交本身,因此任何有权访问该存储库的人都可以找到它,如果他们知道要寻找什么。

        【讨论】:

        • 当然,如果可以访问远程文件系统,你可以像在本地一样简单地清理它。
        • git reflog expire 似乎不起作用,如果我手动浏览历史记录,我仍然可以访问该提交。无论如何,我只是决定安全地删除整个存储库,下次我将从加密驱动器部署,所以我不必经历这个。
        • 而且你也不知道怎么做,只删除历史中间的提交历史?
        • @Denji 假设您没有将它推送到任何地方,您可以使用git rebase 从您的历史记录中删除提交。有很多关于这样做的文档,包括手册页本身。专门寻找--onto 标志。请注意,如果您的合并提交比您尝试删除的提交更新,事情会变得更加复杂。
        • Kevin Ballard,然而,问题在于,在故事的中间有一个提交,我们希望将分支 1 从历史中间移到另一个分支 2(使用继承主) [分支 2 的 1 次提交更改,继承了 master ]
        猜你喜欢
        • 2016-03-13
        • 2014-06-24
        • 2023-01-22
        • 1970-01-01
        • 2013-08-03
        • 2012-12-14
        • 1970-01-01
        • 2014-11-20
        • 2014-07-07
        相关资源
        最近更新 更多