Mark Amery
Mark Amery

Reputation: 155135

Undo push to bare git repo

I've just pushed a whole bunch of commits that I shouldn't have to a bare repo that copies all changed files it receives to our web root using

GIT_WORK_TREE=/var/www git checkout -f

in a post-receive hook.

Because there were a whole load of commits pushed at once, I have no idea what the id was of the previous healthy commit received by the repo.

Is there any way I can undo this push?

Upvotes: 2

Views: 381

Answers (2)

Mark Amery
Mark Amery

Reputation: 155135

This can't really be done.

git reflog, which shows a full history of what commits you've had checked out and what operations moved you between them, is often the proper tool for recovering from incompetence-caused disasters with Git repos; you just look down the history until you see what commit you were on before you did whatever stupid and destructive thing you did, and checkout that commit.

Unfortunately, the reflog is disabled by default for bare repos. Unless you've explicitly enabled core.logAllRefUpdates in your repo's config, git reflog will just return with no output. And if you felt the need to read this question, chances are you haven't explicitly enabled core.logAllRefUpdates.

You might still be able to get the information you need by looking at the reflogs of the remote-tracking branches on your development machines (or whichever repos you push to your bare repo from), as described by Matthieu Moy. But even that option may not be available to you if you don't have access to whichever development machine made the last healthy push.

If that's your situation, I'm afraid you're fucked. The only recourse you have - assuming you have some knowledge about what commit was supposed to be checked out - is to look through the full git log commit history by eye and try checking out commits that you reckon might be the one you want. Enable the reflog or be more careful next time.

Upvotes: 2

Matthieu Moy
Matthieu Moy

Reputation: 16637

As Mark Amery said, the reflog is most likely disabled on the server. But, there's still hope if you have a copy of the repository you pushed from. When you did a push, Git updated a remote-tracking branch (like refs/remotes/origin/master), and probably updated the reflog of this remote-tracking branch.

In the output of git reflog show origin/master, you should find an entry saying update by push corresponding to your push. The entry before corresponds to where you were before the push.

You can also look directly at the log files (e.g. .git/logs/refs/remotes/origin/master) and find entries looking like

acb60f2759717796f807197f6997708528260255 59dbeca4120db70db34144ee14d05cc526b1f5ab Your Self <[email protected]> 1427137007 +0100  update by push

The first sha1 is where you were before, the second where you were after.

But there's no magic: this will give you only the history of the remote-tracking seen by this repository, not a detailed history of who pushed when.

Upvotes: 2

Related Questions