Remove a file from Git history without deleting the file



I used GitHub’s instructions for scrubbing a file from the commit history, but it deleted the file in question from my system. This was surprising to me because the git rm --cached command itself should leave the file itself untouched. But this behavior can also be seen in the worked example on that page: try running ls before and after the big git filter-branch ... command.

I’m using Git 2.6.1.

How can I delete a file from the commit history without deleting the file itself? Obviously I could just make a backup (which I did in my case), but that’s a workaround and not a solution.





When git-filter-branch is done it checks out the new branch head. This will update your working directory to a clean state. The file you wanted obliterated from history has been obliterated. Backing up beforehand is the solution.

If you forgot to back it up, you can still get it back! Git takes a long time to throw things out, your original commits are still in there. After git-filter-branch there will be a branch called original/refs/heads/master (if you filtered master) which contains the original commits. You can recover the file from there.

In general, you can recover filters and rebases using git reflog. It’s a log of every time HEAD changes (ie. you checkout or rebase or merge or filter or…). For example, after doing the Github filter example, git reflog is…

abaabaf (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: filter-branch: rewrite
8ef0c30 (refs/original/refs/remotes/origin/master, refs/original/refs/heads/master) HEAD@{1}: clone:

I can use 8ef0c30 or HEAD@{1} (ie. the previous location of HEAD) or original/refs/remotes/origin/master or original/refs/heads/master to get back to where things were before the filter ran.



Facebook Comments

Post a comment