Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undo git filter-branch

Tags:

git

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?

like image 382
Chin Avatar asked Jan 26 '13 22:01

Chin


People also ask

Does git filter branch rewrite history?

DESCRIPTION. Lets you rewrite Git revision history by rewriting the branches mentioned in the <rev-list options>, applying custom filters on each revision. Those filters can modify each tree (e.g. removing a file or running a perl rewrite on all files) or information about each commit.

How do you use filter branch?

The basic syntax is git filter-branch <filters> branch_name . You can use HEAD or @ to refer to the current branch instead of explicitly typing branch_name . A very simple and useful filter is the subdirectory filter. It makes a given subdirectory the repository root.

Where is git filter repo installed?

This can be installed in the directory pointed to by git --html-path . Note that git filter-repo -h will show a more limited built-in set of instructions regardless of whether the html version of help is installed.

How to undo changes to a private branch in Git?

Git reset should generally be considered a 'local' undo method. A reset should be used when undoing changes to a private branch. This safely isolates the removal of commits from other branches that may be in use by other developers. Problems arise when a reset is executed on a shared branch and that branch is then pushed remotely with git push.

How do I undo a commit in Git checkout?

How to undo a commit with git checkout. Using the git checkout command we can checkout the previous commit, a1e8fb5, putting the repository in a state before the crazy commit happened. Checking out a specific commit will put the repo in a "detached HEAD" state. This means you are no longer working on any branch.

Why does Git git filter-branch refuse to start?

git filter-branch refuses to start with an existing temporary directory or when there are already refs starting with refs/original/, unless forced. This option will cause the mapping from old to new objects to be loaded from named branch upon startup and saved as a new commit to that branch upon exit, enabling incremental of large trees.

What happens when you undo with Git revert?

Undo with: git revert <SHA> What’s happening: git revert will create a new commit that’s the opposite (or inverse) of the given SHA. If the old commit is “matter”, the new commit is “anti-matter”—anything removed in the old commit will be added in the new commit and anything added in the old commit will be removed in the new commit.


2 Answers

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 
like image 145
William Seiti Mizuta Avatar answered Sep 23 '22 20:09

William Seiti Mizuta


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 
like image 28
Eldar Abusalimov Avatar answered Sep 24 '22 20:09

Eldar Abusalimov