Что не так с этим git smudge/clean filter?

Я хочу применить этот фильтр в своем репозитории git, чтобы удалить раздел из файла решения во время извлечения и добавить этот раздел во время фиксации.

Это раздел, который я хочу удалить или добавить:

GlobalSection(SubversionScc) = preSolution
    Svn-Managed = True
    Manager = AnkhSVN - Subversion Support for Visual Studio
EndGlobalSection

Я настроил этот фильтр в моем.git/info/attribute

*.sln filter=SourceControlProvider

и я добавил эти команды в мою конфигурацию

$ git config filter.SourceControlProvider.smudge "sed -e '/GlobalSection(SubversionScc)/,/EndGlobalSection/d' %"
$ git config filter.SourceControlProvider.clean "sed -n -e '/^Global$/ r ankhsvnsection ' < %"

Ну, это не работает. Что я сделал не так?

ankhsvnsection - это текстовый файл, который находится в том же каталоге, что и файл *.sln

1 ответ

Решение

Я вижу несколько вопросов здесь:

  1. У тебя есть % в конце обоих фильтров.
    Это не имеет особого значения и будет передано в качестве дополнительного аргумента для sed, что, вероятно, приведет к ошибке (если у вас нет файла с именем %).
    Фильтры должны быть "потоковыми" (читать из stdin и писать в stdout). Их определение может включать %f, но это не должно рассматриваться как файл для чтения или записи; Git выполняет эту часть, фильтры должны просто читать из stdin и записывать в stdout.

  2. Ваш чистый фильтр пытается перенаправить стандартный ввод с %f,
    Входные данные уже будут на stdin, перенаправлять не нужно.

  3. Программа sed в чистом фильтре использует r Команда для доступа к другому файлу.
    Кажется, что фильтры запускаются из корня рабочего дерева, но я не уверен, гарантировано ли это.

  4. Команда sed в чистом фильтре использует -n, Его единственным выводом будет содержимое ankhsvnsection файл (при условии, что вход имеет Global линия).

  5. Некоторые версии sed (по крайней мере (старая) версия BSD в Mac OS X) не допускают пробелов после имени файла r команда (то есть пробел после ankhsvnsection в программе Sed чистого фильтра).

После добавления, изменения или удаления фильтра вам, вероятно, потребуется коснуться, изменить или удалить файлы рабочего дерева, прежде чем Git применит фильтр. Индекс Git записывает время модификации файлов рабочего дерева; если они не изменились, то Git переведет git checkout -- file а также git add file в неоперативный.

Если вы хотите увидеть фактическое содержание индекса (например, чтобы проверить, что произвел чистый фильтр), вы можете использовать git show :0:path/from/repo/root/to/file, Вы не можете обычно использовать git diff для этого, так как он также применяет фильтры.

Это сработало для меня:

git config filter.SourceControlProvider.smudge "sed -e '/GlobalSection(SubversionScc)/,/EndGlobalSection/d'"
git config filter.SourceControlProvider.clean "sed -e '/^Global\$/ r ankhsvnsection'"
Другие вопросы по тегам