Git Repo, there is a folder ABC
with three files, all having spaces in the name file - 1.ext
, file - 2.ext
, and file - 3.ext
.
Say you begin with a history of
$ git lola --name-status * e709131 (HEAD, master) bar | A bar * 61493ac ABC/file - 3.ext | A ABC/file - 3.ext * 34cce9e ABC/file - 2.ext | A ABC/file - 2.ext * 115e6d5 ABC/file - 1.ext | A ABC/file - 1.ext * 5ea5b42 foo A foo
Note: git lola is a non-standard but highly useful alias.
git rm supports an option for removing subtrees.
-r
Allow recursive removal when a leading directory name is given.
After running
$ git filter-branch --index-filter 'git rm --cached -r --ignore-unmatch ABC' \ --prune-empty --tag-name-filter cat -- --all
you will see output that resembles
Rewrite 115e6d5cd06565ca08f1e5c98c4b91246cf59fa1 (2/5)rm 'ABC/file - 1.ext' Rewrite 34cce9e90f832460137e620ebacc8a73a99e64ce (3/5)rm 'ABC/file - 1.ext' rm 'ABC/file - 2.ext' Rewrite 61493ac3211808f34f616dbc33d51d193b3f45a3 (4/5)rm 'ABC/file - 1.ext' rm 'ABC/file - 2.ext' rm 'ABC/file - 3.ext' Rewrite e709131f1fe6103adf37616c9fa500994aeb30d0 (5/5)rm 'ABC/file - 1.ext' rm 'ABC/file - 2.ext' rm 'ABC/file - 3.ext' Ref 'refs/heads/master' was rewritten
If you are happy with the result, delete the old master with
$ git update-ref -d refs/original/refs/heads/master
and now you have a history of
$ git lola --name-status * 19680d4 (HEAD, master) bar | A bar * 5ea5b42 foo A foo
To answer your second question, say you wanted to delete ABC/file - 2.ext
only. Remember that you will need two layers of quoting: one layer for the whole command and another to escape spaces in an argument to that command, the name of the file to remove.
One way to do that is
$ git filter-branch --index-filter \ 'git rm --cached --ignore-unmatch "ABC/file - 2.ext"' --prune-empty \ --tag-name-filter cat -- --all
Note the double quotes inside the single quotes.
If you had run this command instead, your history would have become
$ git lola * a8d1b0d (HEAD, master) bar * cff0c4e ABC/file - 3.ext * 115e6d5 ABC/file - 1.ext * 5ea5b42 foo