How can I recover from an accidental git push -f?

I just ran git push -f by mistake, thus overwriting a remote branch.

Original:

(remote origin:)
    branch master -> commit aaaaaaa
    branch foo    -> commit bbbbbbb

(local)
    branch master -> commit ccccccc
    branch foo    -> commit ddddddd

After git push -f:

(remote origin:)
    branch master -> commit ccccccc
    branch foo    -> commit ddddddd

In my local repository, I'm working on the master branch, so I can restore the branch master to commit aaaaaaa, because I can get commit aaaaaaa from git reflog. However, I couldn't get commit bbbbbbb because I didn't pull before git push -f.

I have tried git reflog in the remote repository, but there's nothing useful in reflog in the bare repository.

How can I restore the branch foo back to commit bbbbbbb in the remote repository?

(P.S. I don't know the actual value of bbbbbbb.)


Solution 1:

Try this:

  1. Connect to the remote over SSH.

  2. Make a backup of the entire remote repository.

    tar cvzf project-backup.tgz /path/to/project.git
    
  3. If you know at least the first few characters of bbbbbbb, use git show bbbbbb and/or git log bbbbbb to find out the full commit hash. (If you need only the hash, git rev-parse bbbbbb will also work, but it's always better to check.)

    If you don't know the value at all, run git fsck and you should get a list of "dangling commits". Examine each commit using git show <hash> and git log <hash> until you find the correct one.

  4. Update the branch references:

    echo aaaaaaaaaaaaaaa.... > refs/heads/master
    echo bbbbbbbbbbbbbbb.... > refs/heads/foo
    
  5. Use git log master and git log foo to ensure that you restored the correct branches.