How can I recover from an erronous git push -f ori

2019-01-03 13:20发布

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

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

6条回答
smile是对你的礼貌
2楼-- · 2019-01-03 13:39

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 lucky enough to use GitHub or GitHub for Enterprise, you can have a look to the REST API and retrieve lost commit as patch, example:

  1. List events and find the commit sha1 long format

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

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

  1. Apply locally and push again

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

查看更多
神经病院院长
3楼-- · 2019-01-03 13:39

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.

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.

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

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

查看更多
干净又极端
4楼-- · 2019-01-03 13:40

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

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
查看更多
▲ chillily
5楼-- · 2019-01-03 13:41

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.

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)

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!!

查看更多
疯言疯语
6楼-- · 2019-01-03 13:45

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
查看更多
淡お忘
7楼-- · 2019-01-03 14:04

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

If you have the correct source then you could just push it into the remote with the --force option. 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.

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 fsck to see if you can recover things, and above all DO NOT run git gc.

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

查看更多
登录 后发表回答