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
but not
logs/latest/debug.log
Подстановочные символы можно использовать и в именах каталогов.
logs/debug.log logs/debug.log
но не
debug.log
build/logs/debug.log
Шаблоны, указывающие на файл в определенном каталоге, задаются относительно корневого каталога репозитория. (При желании можно добавить в начало косую черту, но она ни на что особо не повлияет.)

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

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

# ignore all logs
*.log

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

# ignore the file literally named foo[01].txt
foo\[01\].txt

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

Обычно правила игнорирования Git задаются в файле .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 "Start ignoring debug.log"

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

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

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

$ cat .gitignore
*.log
  
$ git add -f debug.log
  
$ git commit -m "Force adding debug.log"

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

$ echo !debug.log >> .gitignore
  
$ cat .gitignore
*.log
!debug.log
  
$ git add debug.log
  
$ git commit -m "Adding 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

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

<file containing the pattern> : <line number of the pattern> : <pattern>    <file name>

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

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

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

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