如何从错误的 git push -f origin master 中恢复?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3973994/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:19:34  来源:igfitidea点击:

How can I recover from an erronous git push -f origin master?

gitgit-commitgit-push

提问by David van Dugteren

I just committed the wrong source to my project using --forceoption.

我只是使用--force选项向我的项目提交了错误的源代码。

Is it possible to revert? I understand that all previous branches have been overwritten using -foption, so I may have screwed up my previous revisions.

是否可以恢复?我知道所有以前的分支都被-f选项覆盖了,所以我可能搞砸了我以前的修订。

采纳答案by Cameron Skinner

Git generally doesn't throw anything away, but recovering from this may still be tricky.

Git 通常不会扔掉任何东西,但从中恢复可能仍然很棘手。

If you have the correct source then you could just push it into the remote with the --forceoption. Git won't have deleted any branches unless you told it to. If you have actually lost commits then take a look at this useful guide to recovering commits. If you know the SHA-1 of the commits you want then you're probably OK.

如果您有正确的来源,那么您可以使用该--force选项将其推送到遥控器中。Git 不会删除任何分支,除非你告诉它。如果您确实丢失了提交,请查看此有用的恢复提交指南。如果您知道所需提交的 SHA-1,那么您可能没问题。

Best thing to do: Back everything up and see what is still in your local repository. Do the same on the remote if possible. Use git fsckto see if you can recover things, and above all DO NOT run git gc.

最好的做法:备份所有内容并查看本地存储库中的内容。如果可能,请在遥控器上执行相同操作。使用git fsck,看看你是否能恢复的东西,最重要的不运行git gc

Above above all, never use the --forceoption unless you really, really mean it.

最重要的是,--force除非您真的非常认真,否则永远不要使用该选项。

回答by user1094125

If you know the commit hash, it's easy, just recreate your branch.

如果您知道提交哈希,这很简单,只需重新创建您的分支即可。

5794458...b459f069 master -> master (forced update)
5794458...b459f069 master -> master (forced update)

Delete the remote branch:

删除远程分支:

git push origin :master

then recreate your branch with the following commands:

然后使用以下命令重新创建您的分支:

git checkout 5794458
git branch master
git push origin master

回答by Abdelhafid

The solution is already mentioned here

这里已经提到解决方案

# work on local master
git checkout master

# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}

# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)

# finally, push the master branch (and only the master branch) to the server
git push -f origin master

回答by Pierrick HYMBERT

If you are not on that local repo where the forced push came from, at origin/master level there is no way to recover. But if you are luckyenough to use GitHubor GitHub for Enterprise, you can have a look to the RESTAPI and retrieve lost commit as patch, example:

如果您不在强制推送来自的本地存储库中,则在原始/主级别无法恢复。但是,如果您有幸使用GitHubGitHub for Enterprise,您可以查看RESTAPI 并检索丢失的提交作为补丁,例如:

  1. List events and find the commit sha1 long format
  1. 列出事件并找到提交 sha1 长格式

https://api.github.com/repos/apache/logging-log4j2/events

https://api.github.com/repos/apache/logging-log4j2/events

  1. Download the lost commit and retrieve the related patch in the json path .files[]/patch
  1. 下载丢失的提交并在 json 路径 .files[]/patch 中检索相关补丁

https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

  1. Apply locally and push again
  1. 本地申请再推送

git apply patch.patch && git commit -m "restored commit" && git push origin master

git apply patch.patch && git commit -m "restored commit" && git push origin master

回答by user7610

Another way to recover the lost commit or even to figure out what commits were lost, if the previous push came not from your local repo, is to look at your CI machine.

如果先前的推送不是来自您的本地存储库,则另一种恢复丢失的提交甚至找出丢失的提交的方法是查看您的 CI 机器。

If you have a job which tests the master branch after every commit (or series of consecutive commits), which you should have, you can have a look what it was testing last. That is the commit you need to restore.

如果您有一个在每次提交(或一系列连续提交)后测试 master 分支的作业,您应该拥有它,您可以查看它最后测试的内容。那就是您需要恢复的提交。

The CI machine may even keep a local clone of the repo, from which you may be able to perform this recovery.

CI 机器甚至可以保留一个本地的 repo 克隆,您可以从中执行此恢复。

Source: probably Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation (Addison-Wesley Signature Series (Fowler))

来源:可能是持续交付:通过构建、测试和部署自动化实现可靠的软件发布(Addison-Wesley 签名系列(Fowler))

回答by Pran

I did the same thing while undoing a last push for only one file. Ended up going to back to original state of the repository. I was using git commands from Linus as I had the local copy on Linux. Luckily that copy was still intact.

我在撤消仅对一个文件的最后一次推送时做了同样的事情。最终返回到存储库的原始状态。我使用来自 Linus 的 git 命令,因为我在 Linux 上有本地副本。幸运的是,那个副本仍然完好无损。

All I did was (after frantically making few more copies of the local repo):

我所做的只是(在疯狂地制作了一些本地回购的副本之后):

git add .
git status

(it said that origin/master was ahead by 68 commits, fine ... those were all the commits I deleted)

(它说 origin/master 领先 68 个提交,很好……这些都是我删除的所有提交)

git remote set-url origin <GIT_SSH_URL>
git push

And everything got restored the way it was before I did forceful push. The most important thing to remember is never to do a git checkout . after you had forcefully pushed. But the best practice is to disable push option. I am never using it ever again. Learnt my lesson!!

一切都恢复到我强行推动之前的样子。要记住的最重要的事情是永远不要执行 git checkout 。在你强行推动之后。但最佳做法是禁用推送选项。我再也不会使用它了。吸取我的教训!!

回答by Jacob

Yes you can recover commits after git push -f your_branch

是的,您可以在之后恢复提交 git push -f your_branch

Text from Doc:

Prune entries older than the specified time. If this option is not specified, the expiration time is taken from the configuration setting gc.reflogExpire, which in turn defaults to 90 days. --expire=all prunes entries regardless of their age; --expire=never turns off pruning of reachable entries (but see --expire-unreachable).

来自 Doc 的文字

修剪早于指定时间的条目。如果未指定此选项,则过期时间取自配置设置 gc.reflogExpire,默认为 90 天。--expire=all 修剪条目,无论其年龄如何;--expire=never 关闭可访问条目的修剪(但请参阅--expire-unreachable)。

So you can do:

所以你可以这样做:

1- git reflog

1- git reflog

enter image description here

在此处输入图片说明

2- you choose Head_Number does you want recover with git reset –hard HEAD@{HEAD-NUMBER}

2- 你选择 Head_Number 你想用什么来恢复 git reset –hard HEAD@{HEAD-NUMBER}

enter image description here

在此处输入图片说明

3- you can see all commits on this head by git cherry -v branch_name

3-您可以通过以下方式查看此头上的所有提交 git cherry -v branch_name

4- in the end you should force push git push -f branch_name

4-最后你应该强制推送 git push -f branch_name

OR

或者

1- get the number of SHA from your GIT client (interface)

1- 从您的 GIT 客户端(界面)获取 SHA 的数量

git reset --hard commit_SHA

2- force push

2-力推

git push -f your_branch

Hope this helps

希望这可以帮助

回答by Andrey

Here you can read decisions https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it

在这里你可以阅读决定https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it

The second one helped me. I did wrong these commands

第二个帮助了我。我做错了这些命令

1) (some-branch) git pull -> correct command was git pull origin some-branch

2) (some-branch) git push -f origin some-branch

After these commands I lost three commits. To recover them I looked to terminal where I did wrongly 'git pull' and have seen there output like

在这些命令之后,我丢失了三个提交。为了恢复它们,我查看了我错误地“git pull”的终端,并看到了类似的输出

60223bf...0b258eb some-branch -> origin/some-branch

60223bf...0b258eb 一些分支-> 起源/一些分支

The second hash 0b258eb was exactly what I needed. So, I took this hash and produce command

第二个哈希 0b258eb 正是我所需要的。所以,我拿了这个散列并产生命令

git push --force origin 0b258eb:some-branch