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
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?
2 Solutions collect form web for “Undo push to bare git repo”
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 <Your.Self@example.com> 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.
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
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.