manol
manol

Reputation: 582

How do I enable shell options in git?

I want to use extended globbing in an "index-filter" , e.g.

git filter-branch --index-filter "git rm --cached --ignore-unmatched Modules/!(ModuleA|ModuleB)"

but I get an error:

eval: line 336: syntax error near unexpected token `('

I already tried:

git filter-branch --index-filter "shopt -s extglob && git rm --cached
--ignore-unmatched Modules/!(ModuleA|ModuleB)"

So the general question is: how do I enable specific shell options for the shell used to evaluate these expressions?

Upvotes: 3

Views: 2498

Answers (2)

Jayen
Jayen

Reputation: 6069

I realize this is not what you asked, but may still solve your problem. I made a list of the paths that aren't docs or research and then removed them.

PATHS_TO_REMOVE=$(git log --all --pretty=format: --name-only | sed 's@/.*@@' | sort | uniq | egrep -v '^docs$|^research$' | xargs)
git filter-branch -f --index-filter "git rm -r --cached --ignore-unmatch $PATHS_TO_REMOVE" --tag-name-filter cat -- --all

You should be able to do something similar for subdirectories.

Upvotes: 0

kynan
kynan

Reputation: 13613

You can circumvent the problem by having your shell invoking git filter-branch evaluate the glob for you (assuming you enabled extglob there):

git filter-branch --index-filter "git rm --cached --ignore-unmatch $(ls -xd Modules/!(ModuleA|ModuleB))"

Update: You need to supply parameters to ls: -x to separate entries by space instead of new line and -d to print the directory name instead of its contents. For more than a handful of files you may also need to add -w 1000 (or a similarly large number) to make ls assume a very wide terminal and fit everything in a single line.

Upvotes: 2

Related Questions