#git #git-filter-branch
#git #git-filter-branch
Вопрос:
Я хочу использовать расширенную глобализацию в «фильтре индекса», например
git filter-branch --index-filter "git rm --cached --ignore-unmatched Modules/!(ModuleA|ModuleB)"
но я получаю сообщение об ошибке:
оценка: строка 336: синтаксическая ошибка возле неожиданного токена `(‘
Я уже пробовал:
git filter-branch --index-filter "shopt -s extglob amp;amp; git rm --cached
--ignore-unmatched Modules/!(ModuleA|ModuleB)"
Итак, общий вопрос таков: как мне включить определенные параметры оболочки для оболочки, используемой для вычисления этих выражений?
Ответ №1:
Вы можете обойти проблему, заставив вашу оболочку, вызывающую git filter-branch
для вас, оценить глобус (при условии, что вы включили там extglob):
git filter-branch --index-filter "git rm --cached --ignore-unmatch $(ls -xd Modules/!(ModuleA|ModuleB))"
Обновление: Вам нужно указать параметры для ls
: -x
для разделения записей пробелом вместо новой строки и -d
для печати имени каталога вместо его содержимого. Возможно, вам также потребуется добавить более чем несколько файлов -w 1000
(или аналогично большое количество), чтобы ls
использовать очень широкий терминал и уместить все в одной строке.
Комментарии:
1. похоже, не работает. он находит файлы, которые выводит ls, и выдает в них ошибки.
2. я запустил
git filter-branch --index-filter "git rm --cached --ignore-unmatch $(ls application/!(services|modules))"
. Для каждого файла или каталога, который не соответствует команде $ (ls …), появляется сообщение об ошибке. например: «/usr/lib/git-core /git-filter-branch: 51: eval: scripts: не найдено» . «scripts» — это каталог в /application .3. Проблема в том, что по какой-то причине
$(ls ...)
печатается по столбцам, а не по строкам. Я обновил свой ответ.4. @Bae Вы правы, вы получаете несколько строк, если это больше, чем несколько файлов. Однако вы можете добавить
-w 1000
(или какое-то другое большое число), чтобы заставитьls
использовать очень широкий терминал и вернуть вывод к одной строке.5. Если оболочка, вызывающая ветвь фильтра git, выполняет глобализацию, она оценивается в соответствии с текущим макетом каталога. Я хотел переписать историю с большим количеством изменений структуры каталогов внутри. Это можно решить с помощью фильтра дерева вместо фильтра индекса, но это в несколько раз медленнее, поскольку он выполняет полную проверку для каждой ревизии.
Ответ №2:
Я понимаю, что это не то, что вы просили, но все еще может решить вашу проблему. Я составил список путей, которые не являются docs
or research
, а затем удалил их.
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
Вы должны быть в состоянии сделать что-то подобное для подкаталогов.