Chin
Chin

Reputation: 20675

Undo git filter-branch

I accidentally delete a file from my repo using git filter-branch:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch images/thumb/a.JPG' HEAD

How can I undo this? Is it possible? i.e. is the file permanently deleted?

Upvotes: 88

Views: 34324

Answers (4)

Eldar Abusalimov
Eldar Abusalimov

Reputation: 25483

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

Upvotes: 35

Mr_and_Mrs_D
Mr_and_Mrs_D

Reputation: 34016

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

Upvotes: 8

William Seiti Mizuta
William Seiti Mizuta

Reputation: 7985

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

Upvotes: 165

che
che

Reputation: 12263

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.

Upvotes: 7

Related Questions