Отключить git очистить фильтр для проверки и sta sh pop - PullRequest
0 голосов
/ 26 марта 2020

Мы используем инструмент автоформатирования uncrustify в наших git репозиториях, они запускаются в git clean filter .

Проблема в том, что пользователи иногда отключают свои фильтры (не спрашивайте). Это приводит к плохому форматированию в некоторых коммитах. Проверка этих коммитов при активном чистом фильтре показывает плохое форматирование как diffs.

Фильтр применяется к git diff и другим, и теперь пользователи не могут извлекать еще один коммит (предупреждение о потере изменений), поэтому они отключают свой фильтр и создают больше проблем, так как их легко забыть включите его снова.

Одним из решений является применение автоформатирования в репозитории сервера, я его изучаю. Мне нравится видеть автоформатирование на git diff, поэтому я вижу, что я собираюсь зафиксировать.

Вопрос в том, можем ли мы предотвратить запуск чистого фильтра для определенных операций, таких как checkout, stash pop, и такие?

Есть ли лучшее предложение?

Ответы [ 2 ]

0 голосов
/ 29 марта 2020

РЕДАКТИРОВАТЬ: я получил немного чрезмерного энтузиазма c. Ответ ниже решает фильтр, работающий при каждом приглашении, но не фильтр, вносящий (фактически даже не реальные) изменения в локальные файлы, таким образом предотвращая checkout.


Функция __git_ps1, предоставляемая в git contrib/completion/git-prompt.sh запускает git diff, что, в свою очередь, запускает соответствующие чистые фильтры.

Хотя я не уверен во всех шагах, связанных с нежелательным поведением, похоже, что изменения, созданные чистый фильтр (возможно, вызванный запросом) препятствовал checkout и stash pop, чтобы защитить от возможной потери незафиксированной работы.

Решение состоит в том, чтобы отключить чистые фильтры в операциях git diff git-prompt.sh, используя трюк от @ElpieKay. В этой версии git -prompt. sh она находится в строках 508 и 509.

- git diff --no-ext-diff --quiet || w="*"
- git diff --no-ext-diff --cached --quiet || i="+"
+ git diff --no-ext-diff --quiet -c filter.*.clean=""  || w="*"
+ git diff --no-ext-diff --cached --quiet  -c filter.*.clean="" || i="+"
0 голосов
/ 27 марта 2020

Во-первых, примечание: git checkout вообще не должен запускать чистый фильтр, поскольку он выполняет только индекс → копирование рабочего дерева. 1 При этом запускается фильтр smudge вместо. Чистый фильтр используется только в индексных операциях копирования рабочего дерева.

Поскольку git stash save / git stash push выполняет операции индексного ← рабочего дерева, он будет использовать чистый фильтр.

Sta sh s apply и pop вызывают git merge-recursive, что более сложно. В то время как в индексе происходит некоторое слияние, иногда для этого нужно выполнить удаление и / или очистку, 2 , поэтому здесь вы также увидите некоторые случаи вызова чистого фильтра.

Как ElpieKay предложил в комментарий, быстрый и грязный, но простой способ отключить фильтр, это временно переопределить конфигурацию его драйвера в командной строке с опцией -c внешнего интерфейса: git -c filter.<em>name</em>.<em>type</em>=noop для каждого применимого name (имя драйвера в .gitattributes) и type (clean или smudge).


1 Это верно для git checkout выполняет переключение ветви (операция git switch в Git 2.23 или более поздней версии) или восстановление файла (операция git restore в Git 2.23 или более поздней версии). В любом случае извлечение обновляет индексные копии некоторых файлов, если это необходимо, а затем обновляет копию рабочего дерева из каждой обновленной или выбранной индексной копии.

То есть при использовании git checkout -- <em>paths</em> учитывая paths обновляться в рабочем дереве из копий, уже присутствующих в индексе: для этого требуется смазать. При использовании git checkout <em>tree-ish</em> -- <em>paths</em> данные paths копируются из указанного tree-ish в индекс, а затем копируются в рабочее дерево: для этого также требуется смазать.

Или, при использовании git checkout <em><code>commit или git checkout branch, записи индекса, которые отличаются от предыдущего HEAD и вновь выбранного, обновляются в индексе, а затем копируются в работу. -дерево, которое требует размытия.

2 git merge -X renormalize всегда запускает оба, сначала делает пятно, а затем очищает, перед объединением, для каждого файла в каждом коммите, используя .gitattributes с рабочего дерева. Настройка merge.renormalize в вашей конфигурации имеет тот же эффект, если вы не переопределите это с помощью git merge -X no-renormalize. Хотя git merge-recursive является более низким уровнем, чем git merge, я ожидаю, что он делает довольно похожие вещи для двух коммитов, которые не представлены существующим содержимым рабочего дерева.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...