Reputation: 526
I wish to erase from the git history the contents of a folder (which can recursively have folders). However, some older commits don't even have the folder while some newer commits have files in that folder that I want to keep.
Let's say that folder is foo
(in path /path/to/foo
) and the files to keep are called bar1
and bar2
(e.g., /path/to/foo/bar1
).
I realize this problem is not new. In this question, a long and hard-to-read (for a beginner at least) script is used. This question is more up-to-date and uses git filter-branch
but I didn't understand what the solution ended up being. Finally, this question is probably the most similar but the answer is not "dissected" for someone with no advanced knowledge of git to understand, so it doesn't give me the confidence to try the commands out.
From what I saw, the current approach for git 2.17 is to use git filter-branch
for each branch. Then use either a tree-filter
or index-filter
(from the documentation I'm not able to see the difference in use cases). Finally a git rm
command with a regex that matches the contents of foo
except bar
. The first part of the regex would probably be simple (/path/to/foo/*
) but I'm not sure how to add the exceptions.
I would greatly appreciate it if someone could break this all down when presenting a command that solves this issue.
Upvotes: 1
Views: 324
Reputation: 60285
git filter-branch --index-filter '
dir=path/to/folder
git rm -qr --cached --ignore-unmatch $dir
git reset $GIT_COMMIT -- $dir/file1 $dir/file2 $dir/file3
'
The only difference between an index filter and a tree filter is, the tree filter loads the tree with all the content from the commit and then does your index updates for you by comparing all the content in the tree with what's listed in the index, updating the index to match the new tree content. It's easy, it's just slow and usually needless.
Upvotes: 1