Git рассматривает каждый файл в вашей рабочей копии как файл одного из трех нижеуказанных типов.

  1. Отслеживаемый файл — файл, который был предварительно проиндексирован или закоммичен.
  2. Неотслеживаемый файл — файл, который не был проиндексирован или закоммичен.
  3. Игнорируемый файл — файл, явным образом помеченный для Git как файл, который необходимо игнорировать.

Игнорируемые файлы — это, как правило, артефакты сборки и файлы, генерируемые машиной из исходных файлов в вашем репозитории, либо файлы, которые по какой-либо иной причине не должны попадать в коммиты. Вот некоторые распространенные примеры таких файлов:

  • кэш зависимостей, например содержимое /node_modules или /packages;
  • скомпилированный код, например файлы .o, .pyc и .class;
  • каталоги для выходных данных сборки, например /bin, /out или /target;
  • файлы, сгенерированные во время выполнения, например .log, .lock или .tmp;
  • скрытые системные файлы, например .DS_Store или Thumbs.db;
  • личные конфигурационные файлы IDE, например .idea/workspace.xml.

Игнорируемые файлы перечисляются в специальном файле .gitignore, который регистрируется в корне репозитория. В Git нет специальной команды для указания игнорируемых файлов: вместо этого необходимо вручную редактировать файл .gitignore и указывать в нем новые файлы, которые должны быть проигнорированы. Файлы .gitignore содержат шаблоны, которые сопоставляются с именами файлов в вашем репозитории для определения необходимости игнорировать эти файлы.

Шаблоны игнорирования в Git

Для сопоставления с именами файлов в .gitignore используются шаблоны подстановки. С помощью различных символов можно создавать собственные шаблоны.

Шаблон Примеры соответствия Пояснение*
**/logs logs/debug.log
logs/monday/foo.bar
build/logs/debug.log
Добавьте в начало шаблона две звездочки, чтобы сопоставить каталоги в любом месте репозитория.
**/logs/debug.log logs/debug.log
build/logs/debug.log
но не
logs/build/debug.log
Две звездочки можно также использовать для сопоставления файлов на основе их имени и имени родительского каталога.
*.log debug.log
foo.log
.log
logs/debug.log
Одна звездочка — это подстановочный знак, который может соответствовать как нескольким символам, так и ни одному.
*.log
!important.log
debug.log
trace.log
но не
important.log
logs/important.log
Добавление восклицательного знака в начало шаблона отменяет действие этого шаблона. Если файл соответствует некоему шаблону, но при этом также соответствует отменяющему шаблону, который задан в файле далее, файл не будет проигнорирован.
*.log
!important/*.log
trace.*
debug.log
important/trace.log
но не
important/debug.log
Шаблоны, которые указаны после шаблона, отменяющего игнорирование, снова помечают файлы как игнорируемые, даже если ранее для этих файлов игнорирование было снято.
/debug.log debug.log
но не
logs/debug.log
Косая черта перед именем файла соответствует файлу в корневом каталоге репозитория.
debug.log debug.log
logs/debug.log
Значение по умолчанию, шаблоны соответствуют файлам, находящимся в любом каталоге
debug?.log debug0.log
debugg.log
но не
debug10.log
Знак вопроса соответствует строго одному символу.
debug[0-9].log debug0.log
debug1.log
но не
debug10.log
Квадратные скобки можно также использовать для указания соответствия одному символу из указанного диапазона.
debug[01].log debug0.log
debug1.log
но не
debug2.log
debug01.log
Квадратные скобки соответствуют одному символу из указанного набора.
debug[!01].log debug2.log
но не
debug0.log
debug1.log
debug01.log
Восклицательный знак можно использовать для указания соответствия любому символу кроме символа из указанного набора.
debug[a-z].log debuga.log
debugb.log
но не
debug1.log
Диапазоны могут быть цифровыми или буквенными.
logs logs
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.log
logs/debug.log
logs/important.log
Минуточку! Разве файл logs/important.log из примера слева не должен быть удален из списка игнорируемых?

Нет! Из-за странностей Git, связанных с производительностью, вы не сможете отменить игнорирование файла, который указан как игнорируемый, с помощью шаблона соответствия каталогу
logs/**/debug.log logs/debug.log
logs/monday/debug.log
logs/monday/pm/debug.log
Две звездочки указывают на соответствие множеству каталогов или ни одному.
logs/*day/debug.log logs/monday/debug.log
logs/tuesday/debug.log
но не
logs/latest/debug.log
Подстановочные символы также можно использовать в именах каталогов.
logs/debug.log logs/debug.log
но не
debug.log
build/logs/debug.log
Шаблоны, указывающие на файл в определенном каталоге, относятся к корневому каталогу репозитория. (При желании можно добавить косую черту, но она ни на что особо не повлияет.)

Две звездочки (**) означают, что ваш файл .gitignore находится в каталоге верхнего уровня вашего репозитория, как указано в соглашении. Если в репозитории несколько файлов .gitignore, просто мысленно поменяйте слова «корень репозитория» на «каталог, содержащий файл .gitignore» (и подумайте об объединении этих файлов, чтобы упростить работу для своей команды)*.

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

# игнорировать все журналы
*.log

Если у вас есть файлы или каталоги, в имени которых содержатся спецсимволы шаблонов, то для экранирования этих спецсимволов в .gitignore можно использовать косую черту (\):

# игнорировать файл с точным именем foo[01].txt»
foo\[01\].txt

Общие файлы .gitignore в вашем репозитории

Обычно правила Git ignore указываются в файле .gitignore в корне репозитория. Тем не менее вы можете определить несколько файлов .gitignore в разных каталогах репозитория. Каждый шаблон, находящийся в конкретном файле .gitignore, проверяется относительно каталога, в котором содержится этот файл. Однако проще всего (и этот подход рекомендуется в соглашении) определить один файл .gitignore в корневом каталоге. После регистрации файла .gitignore для него, как и для любого другого файла в репозитории, включается контроль версий, а после публикации с помощью команды push он становится доступен остальным участникам вашей команды. В файл .gitignore, как правило, включаются только те шаблоны, которые будут полезны другим пользователям репозитория.

Персональные правила игнорирования в Git

В специальном файле, который находится в папке .git/info/exclude, можно определить персональные шаблоны игнорирования для конкретного репозитория. Этот файл не имеет контроля версий и не распространяется вместе с вашим репозиторием, поэтому он хорошо подходит для указания шаблонов, которые будут полезны только вам. Например, если у вас есть пользовательские настройки для ведения журналов или специальные инструменты разработки, которые создают файлы в рабочем каталоге вашего репозитория, вы можете добавить их в .git/info/exclude, чтобы они случайно не попали в коммит в вашем репозитории.

Глобальные правила игнорирования в Git

Кроме того, для всех репозиториев в локальной системе можно определить глобальные шаблоны игнорирования Git, установив свойство Git core.excludesFile. Этот файл нужно создать самостоятельно. Если вы не знаете, куда поместить глобальный файл .gitignore, расположите его в домашнем каталоге (позднее его будет легче найти). После создания этого файла необходимо настроить его местоположение с помощью команды git config:

$ touch ~/.gitignore
$ git config --global core.excludesFile ~/.gitignore

Будьте внимательны при указании глобальных шаблонов игнорирования, поскольку для разных проектов актуальны различные типы файлов. Типичные кандидаты на глобальное игнорирование — это специальные файлы операционной системы (например, .DS_Store и thumbs.db) или временные файлы, создаваемые некоторыми инструментами разработки.

Игнорирование ранее закоммиченного файла

Чтобы игнорировать файл, для которого ранее был сделан коммит, необходимо удалить этот файл из репозитория, а затем добавить для него правило .gitignore. Используйте команду git rm с опцией --cached, чтобы удалить этот файл из репозитория, но оставить его в рабочем каталоге как игнорируемый файл.

$ echo debug.log >> .gitignore
$ git rm --cached debug.log
rm 'debug.log'
$ git commit -m "Начать игнорировать файл debug.log"

Опустите опцию --cached, чтобы удалить файл как из репозитория, так и из локальной файловой системы.

Коммит игнорируемого файла

Игнорируемый файл можно принудительно закоммитить в репозиторий с помощью команды git add с опцией -f (или --force):

$ cat .gitignore
*.log
$ git add -f debug.log
$ git commit -m "Принудительное добавление файла debug.log"

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

$ echo !debug.log >> .gitignore
$ cat .gitignore
*.log
!debug.log
$ git add debug.log
$ git commit -m "Добавление файла debug.log"

Этот подход более прозрачен и понятен, если вы работаете в команде.

Скрытие изменений в игнорируем файле

Команда git stash — это мощная функция системы Git, позволяющая временно отложить и отменить локальные изменения, а позже применить их повторно. По умолчанию команда git stash ожидаемо пропускает игнорируемые файлы и скрывает изменения только в тех файлах, которые отслеживаются Git. Тем не менее вы можете вызвать команду git stash с опцией --all, чтобы также скрыть изменения в игнорируемых и неотслеживаемых файлах.

Отладка файлов .gitignore

Если шаблоны .gitignore сложны или разбиты на множество файлов .gitignore, бывает непросто отследить, почему игнорируется определенный файл. Используйте команду git check-ignore с опцией -v (или --verbose), чтобы определить, какой шаблон приводит к игнорированию конкретного файла:

$ git check-ignore -v debug.log
.gitignore:3:*.log debug.log

Вывод показывает:

<файл, содержащий шаблон>: <номер строки шаблона>: <шаблон> <имя файла>

При желании в команде git check-ignore можно передать несколько имен файлов, причем сами имена могут даже не соответствовать файлам, существующим в вашем репозитории.

Готовы изучить Git?

Попробуйте это интерактивное учебное руководство.

Начните прямо сейчас