Undo git filter-branch

Solution 1:

When you use git filter-branch, a backup file is created in

refs/original/refs/heads/master

If you used the command in branch master. You can check if you have the backup in .git/refs directory. With this in mind, you can use this backup to recover your files with:

git reset --hard refs/original/refs/heads/master

Solution 2:

Probably a more proper way than just doing hard reset to the original master would be to restore all refs rewritten by git filter-branch, and maybe even delete backup refs afterwards in order to be able to invoke git filter-branch again without --force:

for orig_ref in $(git for-each-ref --format="%(refname)" refs/original/); do
    git update-ref "${orig_ref#refs/original/}" $orig_ref
    git update-ref -d $orig_ref  # to also remove backup refs
done

And after that:

git reset --hard master

UPD.

Here's (arguably) a bit more git'ish way to perform the same without a shell for-loop:

git for-each-ref --format="update %(refname:lstrip=2) %(objectname)" refs/original/ | git update-ref --stdin
git for-each-ref --format="delete %(refname) %(objectname)" refs/original/ | git update-ref --stdin

Solution 3:

A much cleaner solution is given in this answer by @jthill.

git fetch . +refs/original/*:*

As noted in that answer you may need to detach the HEAD if the currently checked out branch is to be restored.

To delete the refs/original refs, issue:

git for-each-ref refs/original --format='delete %(refname) %(objectname)' | git update-ref --stdin

Solution 4:

It's possible that your old branch tip will be preserved in your reflog. Then you should be able to check out the unchanged commit with all the previous history.