Он реализован сейчас (git 1.9 / 2.0, Q1 2014) с вводной магией pathspec :(exclude)и его краткой формой:! в commit ef79b1f и commit 1649612 , автор
Nguyễn Thái Ngọc Duy ( pclouds) , документацию можно найти здесь .
Теперь вы можете регистрировать все, кроме содержимого подпапки:
git log -- . ":(exclude)sub"
git log -- . ":!sub"
Или вы можете исключить определенные элементы в этой подпапке
конкретный файл:
git log -- . ":(exclude)sub/sub/file"
git log -- . ":!sub/sub/file"
любой данный файл в sub:
git log -- . ":(exclude)sub/*file"
git log -- . ":!sub/*file"
git log -- . ":(exclude,glob)sub/*/file"
Вы можете сделать это исключение нечувствительным к регистру!
git log -- . ":(exclude,icase)SUB"
Как отметил Кенни Эвитт
Если вы запускаете Git в оболочке Bash, используйте ':!sub'или ":\!sub"вместо этого, чтобы избежать bash: ... event not foundошибок
Примечание. Git 2.13 (второй квартал 2017 г.) добавит синоним ^к!
См. Commit 859b7f1 , commit 42ebeb9 (8 февраля 2017 г.) Линус Торвальдс ( torvalds) .
(Объединено Junio C Hamano - gitster- в коммите 015fba3 , 27 февраля 2017 г.)
pathspec magic: добавьте ' ^' как псевдоним для ' !'
Выбор " !" для отрицательной pathspec не только не соответствует тому, что мы делаем для ревизий, но и ужасный символ для расширения оболочки, поскольку он требует цитирования.
Поэтому добавьте ' ^' в качестве альтернативного псевдонима для исключающей записи pathspec.
Обратите внимание, что до Git 2.28 (3 квартал 2020 г.) использование отрицательных pathspec при сборе путей, в том числе неотслеживаемых, в рабочем дереве было нарушено.
См. Commit f1f061e (5 июня 2020 г.) Элайджа Ньюрен ( newren) .
(Объединено Junio C Hamano - gitster- в коммите 64efa11 , 18 июня 2020 г.)
dir: исправить обращение с инвертированными указателями путей
Автор отчета : Джон Милликин.
Подпись: Элайджа Ньюрен.
do_match_pathspec()начал жизнь так match_pathspec_depth_1()и для правильности должен был быть вызван только из match_pathspec_depth(). match_pathspec_depth()позже был переименован в match_pathspec(), поэтому сегодня мы ожидаем, что у do_match_pathspec()него нет прямых вызывающих абонентов за пределами match_pathspec().
К сожалению, это намерение было потеряно с переименованием двух функций, и дополнительные вызовы do_match_pathspec()были добавлены в коммитах 75a6315f74 (" ls-files: добавить соответствие pathspec для подмодулей", 2016-10-07, Git v2.11.0-rc0 - слияние, перечисленное в batch # 11 ) и 89a1f4aaf7 (" dir: если наш путь может соответствовать файлам в каталоге, рекурсивно в него", 2019-09-17, Git v2.24.0-rc0).
Конечно, у do_match_pathspec()него было важное преимущество match_pathspec()- match_pathspec()они жестко кодировали флаги на одно из двух значений, и этим новым вызывающим объектам требовалось передать другое значение для флагов.
Кроме того, хотя do_match_pathspec()прямой вызов был неправильным, вероятно, не было никакой разницы в наблюдаемом конечном выходе, потому что ошибка просто означала, что это fill_diretory()будет рекурсивно в ненужные каталоги.
Поскольку последующие проверки соответствия пути на отдельных путях в каталоге приведут к отфильтровыванию этих дополнительных путей, единственным отличием от использования неправильной функции были ненужные вычисления.
Второй из этих плохих вызовов do_match_pathspec()был задействован - через прямое перемещение или через копирование + редактирование - в ряд более поздних рефакторингов.
См. Коммиты 777b420347 (" dir: синхронизировать treat_leading_path()и read_directory_recursive()", 2019-12-19, Git v2.25.0-rc0 - merge ), 8d92fb2927 (" dir: заменить экспоненциальный алгоритм на линейный", 2020-04-01, Git v2.27.0 -rc0 - объединение указано в пакете № 5 ) и 95c11ecc73 («Исправить подверженный ошибкам fill_directory()API; сделать так, чтобы он возвращал только совпадения», 2020-04-01, Git v2.27.0-rc0 - объединение указано в пакете № 5 ) ,
Последний из них ввел использование в do_match_pathspec()отдельном файле и, таким образом, привел к возврату отдельных путей, которых не должно быть.
Проблема с вызовом do_match_pathspec()вместо match_pathspec()заключается в том, что любые отвергнутые шаблоны, такие как ':! Unwanted_path`, будут игнорироваться .
Добавьте новую match_pathspec_with_flags()функцию, чтобы удовлетворить потребности в указании специальных флагов, при этом все еще правильно проверяя отрицательные шаблоны, добавьте большой комментарий выше, do_match_pathspec()чтобы предотвратить его неправильное использование другими, и исправьте текущие вызывающие абоненты do_match_pathspec()вместо использования либо match_pathspec()или match_pathspec_with_flags().
И последнее замечание: DO_MATCH_LEADING_PATHSPECпри работе с DO_MATCH_EXCLUDE.
Дело в DO_MATCH_LEADING_PATHSPECтом, что если у нас есть путь вроде
*/Makefile
и мы проверяем путь к каталогу, например
src/module/component
что мы хотим считать это совпадением, чтобы мы рекурсивно перешли в каталог, потому что у него _might_ есть файл с именем Makefileгде-то ниже.
Однако, когда мы используем шаблон исключения, то есть у нас есть pathspec, например
:(exclude)*/Makefile
мы НЕ хотим говорить, что путь к каталогу, например
src/module/component
является (отрицательным) совпадением.
Хотя где-то под этим каталогом может быть файл с именем «Makefile», могут быть и другие файлы, и мы не можем упреждающе исключить все файлы в этом каталоге; нам нужно выполнить рекурсию, а затем проверить отдельные файлы.
Отрегулируйте DO_MATCH_LEADING_PATHSPECлогику, чтобы она активировалась только для положительных характеристик пути.
!f() { git log ... | path/to/filter-log.pl "$@" | git log --stdin --no-walk; f, или даже обернуть эту часть конвейера в скрипт.