Файл gitignore - примеры и документация

Для чего нужен .gitignore

Файл .gitignore используется для того, чтобы определить, какие файлы и папки не нужно добавлять в git репозиторий.

Мы конечно могли бы вручную добавлять нужные файлы в репозиторий, например так:

git add path/to/file

Однако это было бы очень трудоемко. Гораздо проще использовать команду:

git add .

Которая добавит все файлы в каталоге проекта.

Но что если нам не нужны абсолютно все файлы, а есть файлы например в каталоге /cache или /images или /runtime проекта, которые генерируются в процессе работы. Они не должны быть добавлены в репозиторий.

Тут нам и нужен .gitignore. Вам нужно его самим создать и разместить в корне проекта либо нужной подпапке.

Где должен находиться этот файл

Файл может находиться в корне проекта или любом подкаталоге.

Либо можно задать глобальный файл gitignore, таким образом:

$ git config --global core.excludesfile ~/.gitignore_global

Таким образом вы сможете записать в глобальный файл ~/.gitignore_global настройки, общие для всех ваших проектов. В нем могут храниться например файлы для игнорирования, которые специфичны для вашей IDE, и по этому не логично добавлять их в репозиторий. Однако файлы, которые специфичны для конкретного проекта, обязательно нужно добавлять в .gitignore самого проекта.

Примеры содержимого .gitignore файла

# строки начинающиеся на # - это комментарии, они не учитываются

# Исключить все файлы с расширение .a
*.a

# Но отслеживать файл lib.a даже если он подпадает под исключение выше
!lib.a

# Исключить файл TODO в корневом каталоге, но не файл в subdir/TODO
/TODO

# Игнорировать все файлы в каталоге build/
build/

# Игнорировать файл doc/notes.txt, но не файл doc/server/arch.txt
doc/*.txt

# Игнорировать все .txt файлы в каталоге doc/
doc/**/*.txt

Подробнее о шаблонах игнорирования

ШаблонПримеры соответствияПояснение*
**/logslogs/debug.log logs/monday/foo.bar build/logs/debug.logДобавьте в начало шаблона две звездочки, чтобы сопоставлять каталоги в любом месте репозитория.
**/logs/debug.loglogs/debug.log build/logs/debug.log но не logs/build/debug.logДве звездочки можно также использовать для сопоставления файлов на основе их имени и имени родительского каталога.
*.logdebug.log foo.log .log logs/debug.logОдна звездочка — это подстановочный знак, который может соответствовать как нескольким символам, так и ни одному.
*.log !important.logdebug.log trace.log но не important.log logs/important.logДобавление восклицательного знака в начало шаблона отменяет действие шаблона. Если файл соответствует некоему шаблону, но при этом также соответствует отменяющему шаблону, указанному после, такой файл не будет игнорироваться.
.log !important/.log trace.*debug.log important/trace.log но не important/debug.logШаблоны, указанные после отменяющего шаблона, снова будут помечать файлы как игнорируемые, даже если ранее игнорирование этих файлов было отменено.
/debug.logdebug.log но не logs/debug.logКосая черта перед именем файла соответствует файлу в корневом каталоге репозитория.
debug.logdebug.log logs/debug.logПо умолчанию шаблоны соответствуют файлам, находящимся в любом каталоге
debug?.logdebug0.log debugg.log но не debug10.logЗнак вопроса соответствует строго одному символу.
debug[0-9].logdebug0.log debug1.log но не debug10.logКвадратные скобки можно также использовать для указания соответствия одному символу из заданного диапазона.
debug[01].logdebug0.log debug1.log но не debug2.log debug01.logКвадратные скобки соответствуют одному символу из указанного набора.
debug[!01].logdebug2.log но не debug0.log debug1.log debug01.logВосклицательный знак можно использовать для указания соответствия любому символу, кроме символов из указанного набора.
debug[a-z].logdebuga.log debugb.log но не debug1.logДиапазоны могут быть цифровыми или буквенными.
logslogs logs/debug.log logs/latest/foo.bar build/logs build/logs/debug.logБез косой черты в конце этот шаблон будет соответствовать и файлам, и содержимому каталогов с таким именем. В примере соответствия слева игнорируются и каталоги, и файлы с именем logs
logs/logs/debug.log logs/latest/foo.bar build/logs/foo.bar build/logs/latest/debug.logКосая черта в конце шаблона означает каталог. Все содержимое любого каталога репозитория, соответствующего этому имени (включая все его файлы и подкаталоги), будет игнорироваться
logs/ !logs/important.loglogs/debug.log logs/important.logМинуточку! Разве файл logs/important.log из примера слева не должен быть исключен нз списка игнорируемых? Нет! Из-за странностей Git, связанных с производительностью, вы не можете отменить игнорирование файла, которое задано шаблоном соответствия каталогу
logs/**/debug.loglogs/debug.log logs/monday/debug.log logs/monday/pm/debug.logДве звездочки соответствуют множеству каталогов или ни одному.
logs/*day/debug.loglogs/monday/debug.log logs/tuesday/debug.log but not logs/latest/debug.logПодстановочные символы можно использовать и в именах каталогов.
logs/debug.loglogs/debug.log но не debug.log build/logs/debug.logШаблоны, указывающие на файл в определенном каталоге, задаются относительно корневого каталога репозитория. (При желании можно добавить в начало косую черту, но она ни на что особо не повлияет.)

Что если файлы из gitignore уже добавлены в репозиторий

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

Нам придется вручную их удалить из репозитория.

Очень удобная команда bash, которая удалит из git репозитория те файлы, которые содержатся в файлах .gitignore:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

То же самое для Powershell

foreach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }

При выполнении этой команды, файлы останутся у вас на диске, однако из репозитория они будут удалены.

Либо можно удалять файлы вручную, таким образом:

git rm --cached path/to/file

Либо если нам нужно удалить целую директорию из git, то воспользуемся следующей командой:

git rm  -r --cached path/to/directory

Либо так мы могли бы удалить все файлы с расширением .log в папке log:

git rm --cached log/\*.log

Параметр --cached означает, что файлы будут удалены только из раздела "проиндексированных файлов". На диске (рабочем каталоге) они останутся нетронутыми.

Как понять, почему игнорируется конкретный файл

Запустите команду вместо path/to/file следует указать путь к файлу.

git check-ignore -v path/to/file

В итоге мы получим ответ, в котором содержится конкретная строка .gitignore, благодаря которой данный файл игнорируется.

Отобразить все игнорируемые файлы:

git status --ignored

Очистить проект от всех игнорируемых файлов:

git clean -fX

Используйте с осторожностью. Убедитесь что у вас есть резервная копия.

Документация

Читайте подробную документацию по этой ссылке: https://git-scm.com/docs/gitignore