如何恢复上次提交并将其从历史记录中删除?

时间:2012-01-18 01:14:30

标签: git git-revert

我做了一次提交,并以

还原
git revert HEAD^

只是git log

➜  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 - 所有它仍会出现。我需要将其从历史中删除,因为它有敏感信息

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?

5 个答案:

答案 0 :(得分:54)

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

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

如果这不是一个安全的假设(虽然如果不是我喜欢听到原因),那么你需要使你的reflog过期并强制收集现在收集所有未完成对象的垃圾收集。你可以用

做到这一点
git reflog expire --expire=now --expire-unreachable=now --all
git gc --prune=now

虽然只有你真的绝对需要这样做才能做到。


如果已经推送了你的提交,那么你几乎没有运气。您可以执行强制推送以远程还原它(尽管只有远程端允许),但您无法从远程端的数据库中删除提交本身,因此任何有权访问该存储库的人都可以找到它知道该找什么。

答案 1 :(得分:34)

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

git reset --hard HEAD~

吹走提交。

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

git reset HEAD~

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

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

答案 2 :(得分:7)

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

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

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

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

答案 3 :(得分:5)

如果您尚未推送提交,则可以:

git reset --hard HEAD~2

(HEAD~2删除原始提交和“还原”提交)。

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

答案 4 :(得分:0)

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

  1. 克隆存储库并找到最后一个“良好”提交(.... 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. 替换远程分支(通过删除并推动temp)
git push origin --delete dev_branch
git push origin temp_branch:dev_branch