Как мне включить параметры оболочки в git?

#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
  

Вы должны быть в состоянии сделать что-то подобное для подкаталогов.