guide

Синтаксис шаблонов .gitignore: полный обзор

Синтаксис шаблонов gitignore с таблицами примеров: комментарии, экранирование и конечные пробелы, отрицание !, завершающий слеш, привязка, подстановочные знаки *, ? и [], правила для **.

Каждая строка .gitignore — это один шаблон. Синтаксис похож на glob в командной оболочке, но смысл сильно зависит от положения слеша и положения **. Изложенное ниже опирается на официальную документацию git gitignore(5), а примеры проверены вручную в git 2.50.

Пустые строки, комментарии, экранирование

Конечные пробелы невидимы и потому часто становятся причиной ошибок. Если правило не срабатывает, включите в редакторе отображение пробелов. Помните также, что удаляются только пробелы, а символы табуляции — нет.

Завершающий слеш: только каталоги

Если шаблон оканчивается на /, он совпадает только с каталогами. build/ игнорирует каталог build и всё его содержимое, но не файл с именем build. Напротив, build без слеша совпадает и с файлами, и с каталогами с таким именем.

Слеш фиксирует положение

Если в шаблоне, не считая завершающего слеша, есть / в начале или в середине, он совпадает только с путями относительно каталога, в котором лежит .gitignore. Это обычно называют привязкой (anchoring). Без / git ищет совпадающие имена на любой глубине ниже места расположения .gitignore.

ШаблонСовпадаетНе совпадает
debug.logdebug.log, logs/debug.log
/debug.logdebug.loglogs/debug.log
logs/debug.loglogs/debug.logapp/logs/debug.log
doc/frotz/каталог doc/frotz/a/doc/frotz/
frotz/каталоги frotz/, a/frotz/файл frotz

Особенно путает третья строка. В logs/debug.log есть слеш в середине, поэтому шаблон привязан к корню и означает то же, что и с / в начале. Чтобы поймать logs/debug.log на любой глубине, используйте **/logs/debug.log.

Подстановочные знаки: *, ?, [ ]

Две звёздочки **

** имеет особый смысл только рядом со слешем.

ФормаСмыслПримеры
**/foofoo на любой глубинеfoo, a/foo, a/b/foo
**/logs/debug.loglogs/debug.log на любой глубинеlogs/debug.log, app/logs/debug.log
abc/**всё внутри abcabc/x, abc/x/y (но не сам abc)
a/**/bноль или больше каталогов между нимиa/b, a/x/b, a/x/y/b

В остальных позициях, например в foo** или **bar, ** ведёт себя как обычная * и не переходит через слеш. docs/**/*.pdf совпадает и с docs/manual.pdf, и с docs/a/b/manual.pdf, потому что /**/ совпадает и с нулём каталогов.

Итог на одном небольшом примере

# Результаты сборки (только каталог build в корне)
/build/

# Лог-файлы на любой глубине, но важный лог оставляем
*.log
!important.log

# Все PDF внутри docs
docs/**/*.pdf

# Файл, имя которого начинается с #
\#scratch.md
ПутьРезультатРешающее правило
build/app.jsигнорируется/build/
src/build/app.jsотслеживаетсянет
logs/server.logигнорируется*.log
logs/important.logотслеживается!important.log
docs/api/v1.pdfигнорируетсяdocs/**/*.pdf
#scratch.mdигнорируется\#scratch.md

Эту таблицу можно воспроизвести, вставив правила и пути во вкладку Тест шаблонов генератора.

Источники

← НазадЧто игнорировать, а что коммитить