Reputation: 20675
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
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
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
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
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