Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to recover from a git push -force?

Tags:

git

github

Here is what happened:

I have two remote git branches: master and feature1. For some reason I have to use git push --force for the feature1 branch, but I didn't know when I use git push --force it will also push the master branch. Then, a disaster happened, as I pushed my local master branch to the remote repository.

Luckily, my local branch is not too far away from the remote. Basically, my remote master has two pull requests merged ahead of my local master.

So my problem is: can I reopen the pull request and remerge? I noticed that there is commit version for merge request, so I am worried if I simply make new pull request it will mess up something? Ideally I just want to redo the merging of the two requests.

Is there some other way to recover from this disaster? I learned the --force is a really, really bad choice. :(

Update, example of what happened:

I have following branches:

master feature1 origin/master origin/feature1 

I integrate two pull requests by using the GitHub's Auto merge pull requests. Then, I didn't fetch the master branch on my local machine. Thus, I think my origin/master is two versions behind the remote master.

Then I accidentally used git -f push, which overwrote the remote branch and now I lost the commits from the pull requests on remote repository.

How can I recover from it without messing up other contributors' history?

like image 684
Brian Avatar asked Sep 24 '12 15:09

Brian


People also ask

Can you undo a push in git?

To revert, you can: Go to the Git history. Right click on the commit you want to revert. Select revert commit.

How do I revert after pushing?

If you want to revert the last commit just do git revert <unwanted commit hash> ; then you can push this new commit, which undid your previous commit.

How do you recover a commit?

The first step to recovering your lost commits is to recover the list of all your previous commits and actions done on the repository. Note: Keep in mind that the given commit hashes and signatures may differ from that of your local repository. Replace all relevant information with the info corresponding to your log.


2 Answers

When working with github, refer to GHugo's answer which gives a foolproof procedure with github. If you're on an in-house (or other non-github) installation, read on.

You can always restore the previously observed state of master, by resetting to the old commit and issuing another push -f. The steps involved typically look like this:

# 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 

Note, however, that this restores remote master to the state most recently retrieved by git fetch or equivalent. Any commits pushed by others after the last time you fetched will be lost. However, those commits will still be available in their reflogs, so they can restore them using steps like the above.

like image 77
user4815162342 Avatar answered Sep 17 '22 11:09

user4815162342


Note that, with Github, you can use the API to recover a forced push even if you do not have the repository cloned locally (i.e., when you do not have a reflog), or the commit sha.

First, you must get the previous commit sha, the one before the forced push:

curl -u <username> https://api.github.com/repos/:owner/:repo/events 

Then you can create a branch from this sha:

curl -u <github-username> -X POST -d '{"ref":"refs/heads/<new-branch-name>", "sha":"<sha-from-step-1>"}' https://api.github.com/repos/:owner/:repo/git/refs 

Finally, you can clone the repository locally, and force push again to master:

git clone repo@github git checkout master git reset --hard origin/<new-branch-name> git push -f origin master 

Note that with two-factor authentication, you need to provide a token (see here for more information).

Credit: Sankara Rameswaran

like image 44
GHugo Avatar answered Sep 20 '22 11:09

GHugo