Игнорирование файлов в Git - как правильно использовать .gitignore

17 декабря 2025
Автор

Олег Марков

Введение

Файл .gitignore — один из тех инструментов Git, о котором часто вспоминают только тогда, когда в репозиторий случайно попадает что-то лишнее: огромный лог, секретный ключ, артефакты сборки или временные файлы IDE.

Смотрите, я покажу вам, как с помощью одного небольшого текстового файла можно:

  • исключать из коммитов сгенерированные файлы и каталоги сборки;
  • не допускать попадания в репозиторий конфиденциальных данных;
  • поддерживать репозиторий в чистоте, чтобы в истории были только действительно важные изменения.

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

Что такое .gitignore и как он работает

Общая идея .gitignore

Файл .gitignore — это текстовый файл, в котором вы перечисляете шаблоны файлов и папок, которые Git не должен отслеживать.

Ключевой момент: .gitignore влияет только на неотслеживаемые файлы. Если файл уже был добавлен в репозиторий и закоммичен, просто добавить его в .gitignore недостаточно — Git продолжит его видеть.

Git при каждом статусе/коммите:

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

Где хранится .gitignore

Файл .gitignore может находиться в нескольких местах:

  • в корне репозитория — проектный .gitignore;
  • в подкаталогах — локальные .gitignore для отдельных директорий;
  • глобальный .gitignore для вашего пользователя в системе;
  • файл .git/info/exclude — локальный игнор только для конкретного клона репозитория.

Давайте разберем каждый вариант подробнее.

Типы .gitignore и их приоритет

Проектный .gitignore (в корне репозитория)

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

Пример типичного .gitignore в корне:

# Игнорируем каталоги сборки
build/
dist/

# Игнорируем временные файлы редакторов
*.swp   # Временные файлы Vim
*.tmp   # Разные временные файлы

# Игнорируем логи
logs/
*.log

Комментарии начинаются с #. Пустые строки игнорируются.

Локальные .gitignore в подкаталогах

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

Например, структура:

project/
  .gitignore
  backend/
    .gitignore
  frontend/
    .gitignore
  • Корневой .gitignore описывает общие правила для всего проекта.
  • В backend/.gitignore вы можете добавить специфичные для бэкенда файлы, например миграции какого-то формата или артефакты сборки.
  • В frontend/.gitignore — игнорировать node_modules/, файлы бандла, карты исходников и т.д.

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

Глобальный .gitignore (для всего пользователя)

Глобальный игнор — это файл, который применяется ко всем репозиториям текущего пользователя. Обычно в нем хранятся правила, связанные с вашей средой разработки:

  • временные файлы IDE;
  • файлы ОС (например, .DS_Store в macOS);
  • общие конфигурации редакторов, которые вы не хотите случайно закоммитить.

Как настроить глобальный .gitignore:

  1. Создайте файл, например в домашней директории:

    touch ~/.gitignore_global
    
  2. Укажите Git использовать его:

    git config --global core.excludesfile ~/.gitignore_global
    
  3. Добавьте в него, например:

    # macOS системные файлы
    .DS_Store
    
    # IDE
    .idea/
    .vscode/
    
    # Файлы резервных копий
    *~
    

Обратите внимание: глобальный .gitignore не коммитится, он применяется только у вас локально.

.git/info/exclude — игнор только для текущего клона

Если вам нужно игнорировать какие-то файлы только в конкретном клоне репозитория, и вы не хотите (или не можете) менять проектный .gitignore, используйте файл:

.git/info/exclude

Это по сути такой же .gitignore, но:

  • он не коммитится;
  • не виден другим разработчикам;
  • действует только в этом конкретном репозитории.

Пример использования: вы храните локальный конфигурационный файл local.env, который не должен быть общим для команды. Вы можете добавить его в .git/info/exclude, не меняя общий .gitignore.

Синтаксис и шаблоны в .gitignore

Теперь давайте разберемся, как именно писать правила в .gitignore. От правильных шаблонов зависит, будут ли файлы корректно игнорироваться.

Базовые правила

  1. Одна строка — одно правило.
  2. Пустые строки игнорируются.
  3. Комментарии начинаются с #.
  4. Пробел в начале строки считается частью шаблона (если только строка не начинается с #).

Пример:

# Это комментарий

# Игнорируем все .log файлы
*.log

# Игнорируем папку tmp
tmp/

Шаблоны с символом * (звездочка)

* — это подстановка для любого количества любых символов, кроме разделителя пути /.

Примеры:

*.log      # Игнорируем все файлы, оканчивающиеся на .log
temp*      # Игнорируем все, что начинается с "temp" (temp, temp1, temp_file.txt)
*backup*   # Игнорируем все, где в имени есть "backup"

Обратите внимание, что * не переходит через /. То есть:

*/*.log    # Игнорируются только .log файлы, которые лежат ровно в одном подкаталоге

Шаблоны с ? (один символ)

? соответствует ровно одному любому символу, кроме /.

file?.txt  # file1.txt, fileA.txt, но не file10.txt

Шаблоны с [] (набор символов)

Скобки [] позволяют указать набор допустимых символов или диапазон:

file[0-9].txt   # file0.txt, file1.txt, ..., file9.txt
file[ab].txt    # filea.txt, fileb.txt

Слэш / и относительность путей

Слэш / в .gitignore важен, потому что он определяет, как Git трактует шаблон.

  • Если путь не начинается со слэша, правило применяется к любому уровню вложенности.
  • Если путь начинается со слэша, он интерпретируется относительно каталога, где лежит этот .gitignore.

Примеры:

# Игнорирует любой каталог build на любом уровне
build/

# В корневом .gitignore
/build/      # Игнорирует только build в корне репозитория

# Игнорирует все README.txt на любом уровне
README.txt

# В корневом .gitignore:
/README.txt  # Игнорирует только README.txt в корне

Давайте разберем пример структуры, чтобы это было понятнее:

project/
  .gitignore          # содержит: /config.json
  config.json         # будет проигнорирован
  sub/
    config.json       # НЕ проигнорирован, правило относится только к корню

Если же правило без начального /:

config.json   # Игнорирует все config.json в проекте

Игнорирование каталогов

Чтобы явно указать, что вы хотите игнорировать каталог, добавьте слэш в конце:

logs/         # Любая папка logs с любым содержимым
tmp/          
dist/

Если вы напишете просто:

logs

Git будет воспринимать это как правило и для файлов, и для папок с таким именем. В большинстве случаев удобнее явно использовать слэш для каталогов — это делает правило понятнее.

Отмена игнорирования с помощью !

Иногда нужно «разигнорировать» конкретный файл или каталог внутри игнорируемого. Для этого используется восклицательный знак ! в начале строки.

Давайте разберемся на примере:

# Игнорируем все логи
*.log

# Но один конкретный файл логов нам нужен
!important.log

Как видите, этот код в .gitignore говорит Git:

  • не показывать в статусе все *.log;
  • но файл important.log все же учитывать.

Более сложный пример — частично игнорируем каталог:

# Игнорируем весь каталог config
config/

# Но файл config/example.yml нужно оставить
!config/
!config/example.yml

Здесь важный момент: чтобы «добраться» до файла, вам нужно:

  1. Сначала разигнорировать каталог config/;
  2. Потом разигнорировать нужный файл.

Если вы оставите только:

config/
!config/example.yml

То Git все равно не увидит example.yml, потому что родительская папка уже проигнорирована.

Использование шаблонов ** (рекурсивные пути)

Двойная звездочка ** работает как «любой уровень вложенности каталогов». Эта возможность особенно удобна в сложных структурах.

Примеры:

# Игнорировать все .log во всех подпапках любого уровня
**/*.log

# Игнорировать все каталоги build на любом уровне
**/build/

# Игнорировать все .tmp файлы в подпапках src любого уровня
src/**/**/*.tmp

Чаще всего вы будете видеть простые варианты:

**/node_modules/
**/.DS_Store

Но имейте в виду, что многие случаи и без ** уже корректно работают, потому что обычный шаблон без / и так применяется на всех уровнях.

Порядок применения правил и приоритет

Git применяет правила .gitignore сверху вниз и учитывает:

  1. Последнее подходящее правило для файла — главное.
  2. Более конкретные правила могут переопределять общие.
  3. Локальные .gitignore «ближе» к файлу имеют больший приоритет, чем корневые.

Пример с переопределением

Давайте посмотрим, что происходит в следующем примере:

# Игнорируем все .log
*.log

# Но файл в корне нужен
!important.log
  • Сначала Git видит правило *.log — файл important.log подпадает под него.
  • Затем он встречает правило !important.log — и отменяет игнорирование конкретно для этого файла.

Еще пример:

# Игнорировать все в каталоге logs
logs/

# Кроме errors.log в корне logs
!logs/errors.log

Если в logs/ есть вложенные подкаталоги, они останутся проигнорированными, но logs/errors.log будет виден.

Взаимодействие разных .gitignore

Представьте структуру:

project/
  .gitignore            # 1
  api/
    .gitignore          # 2
    logs/
      api.log
  logs/
    app.log

Содержимое корневого .gitignore:

logs/

Содержимое api/.gitignore:

!logs/

Что произойдет:

  • В корневом .gitignore правило logs/ говорит: игнорировать любые папки с именем logs.
  • В api/.gitignore есть правило !logs/, которое применяется только в каталоге api и ниже.
  • В результате:
    • logs/app.log — проигнорирован (подпадает под корневое правило, локального переопределения нет).
    • api/logs/api.log — не проигнорирован (локальное правило в api/.gitignore отменяет игнорирование для api/logs/).

Работа с уже отслеживаемыми файлами

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

Здесь важно понимать: .gitignore не удаляет и не перестает отслеживать файлы, которые уже находятся в индексе Git. Он управляет только тем, какие новые файловые пути не должны попадать в индекс.

Как перестать отслеживать файл, который уже в репозитории

Если вы случайно закоммитили файл, а затем решили его игнорировать:

  1. Добавьте его в .gitignore.
  2. Удалите его из индекса, но не из файловой системы.

Команды:

# Удаляем файл из индекса, но оставляем на диске
git rm --cached path/to/file.ext

# Фиксируем изменения (удаление файла из репозитория)
git commit -m "Stop tracking file.ext and add to .gitignore"

Комментарий к коду:

git rm --cached path/to/file.ext
# Опция --cached говорит Git:
# "убери файл только из индекса (репозитория),
# но не удаляй его с диска".

Теперь файл будет:

  • присутствовать только у вас локально;
  • не будет отслеживаться Git;
  • скрываться в статусе благодаря записи в .gitignore.

Массовое прекращение отслеживания по шаблону

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

# Обновляем индекс с учетом .gitignore
git rm -r --cached .

# Повторно добавляем все файлы (но уже без проигнорированных)
git add .

git commit -m "Apply .gitignore rules to existing files"

Комментарии:

git rm -r --cached .
# Удаляем из индекса все файлы рекурсивно, но не с диска

git add .
# Добавляем обратно только те файлы, которые не игнорируются
# согласно текущему .gitignore

С этим подходом будьте аккуратны в командной работе — перед выполнением таких команд убедитесь, что понимаете, какие файлы будут затронуты.

Типичные шаблоны .gitignore для разных проектов

Теперь давайте посмотрим на практические примеры, чтобы вам было проще взять готовые решения и адаптировать под свои проекты.

Общие шаблоны для большинства проектов

Часто во многих проектах используются одинаковые правила:

# Логи
logs/
*.log

# Временные файлы ОС
.DS_Store      # macOS
Thumbs.db      # Windows

# Временные файлы редакторов
*.swp          # Vim
*.swo
*~

Здесь я размещаю пример, чтобы вам было проще понять, что стоит сразу исключать в любых репозиториях.

Пример .gitignore для Node.js проекта

# Зависимости
node_modules/

# Сборка и бандлы
dist/
build/

# Кэш
.npm/
.yarn/cache/
.yarn/*
!.yarn/patches/
!.yarn/plugins/
!.yarn/releases/
!.yarn/sdks/
!.yarn/versions/

# Логи
logs/
*.log

# Env файлы
.env
.env.local
.env.*.local

# Инструменты
coverage/          # Результаты тестов
.vscode/
.idea/

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

Пример .gitignore для Python проекта

# Байт-код Python
__pycache__/
*.py[cod]
*$py.class

# Виртуальные окружения
venv/
.env/
.venv/

# Логи и отладочная информация
*.log

# Результаты тестов
.cache/
.coverage
htmlcov/

# Сборка пакетов
build/
dist/
*.egg-info/

# IDE
.idea/
.vscode/

Пример .gitignore для проектов на Go

# Бинарники Go
*.exe
*.exe~
*.dll
*.so
*.dylib

# Собранные бинарники
bin/
build/

# Тестовые артефакты
*.test
coverage.out

# IDE
.idea/
.vscode/

Использование готовых шаблонов из GitHub

GitHub предоставляет большое количество готовых .gitignore для разных языков и фреймворков: Java, .NET, Laravel, Django, React и многие другие.

Вы можете посмотреть их здесь:
https://github.com/github/gitignore

Удобный подход:

  1. Найти подходящий шаблон (например, Python.gitignore).
  2. Скопировать его содержимое.
  3. Вставить в свой .gitignore и при необходимости адаптировать.

Проверка и отладка .gitignore

Иногда вы добавляете правило в .gitignore, но Git «как будто не замечает его». Давайте посмотрим, что можно сделать в таких ситуациях.

Проверить, почему файл игнорируется или нет

Git предоставляет команду:

git check-ignore -v path/to/file

Комментарии:

git check-ignore -v path/to/file
# Показывает:
# - применяется ли к файлу правило игнора
# - из какого файла .gitignore оно взято
# - номер строки с правилом

Пример:

git check-ignore -v logs/app.log

Вы можете увидеть что-то вроде:

.gitignore:3:logs/    logs/app.log

Это означает, что файл игнорируется из-за третьей строки в .gitignore.

Если файл не игнорируется, команда не выведет ничего и вернет ненулевой код возврата.

Проверить, какие файлы игнорируются в целом

Иногда полезно увидеть список файлов, которые Git не показывает вам в статусе:

git status --ignored

Эта команда покажет, какие файлы:

  • неотслеживаемые;
  • проигнорированные .gitignore.

Лучшие практики использования .gitignore

Разделяйте «локальные» и «проектные» правила

Давайте разберемся на примере:

  • В проектный .gitignore лучше добавлять:

    • каталоги сборки (build, dist);
    • зависимостные директории (node_modules, vendor, target);
    • логи, временные фалы, кэш тестов;
    • стандартные временные файлы IDE, если ими пользуется вся команда.
  • В глобальный .gitignore лучше добавить:

    • файлы вашей ОС (.DS_Store, Thumbs.db);
    • файлы конкретных редакторов, которыми пользуетесь лично;
    • кэш или вспомогательные файлы, которые не должны «протекать» в проекты.

Так вы избежите засорения проектного .gitignore сугубо личными настройками.

Не храните в репозитории секреты и конфиденциальные данные

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

  1. Сразу добавьте общие шаблоны в .gitignore:
    • .env
    • *.key
    • *.pem
  2. Используйте шаблоны конфигов вида:
    • config.example.yml (в репозитории)
    • config.yml (в .gitignore, локальная копия с настоящими секретами)

Пример:

# Реальные конфиги локальной среды
config.yml
.env
secrets.json

А в репозитории храните только пример:

# config.example.yml
database:
  host: localhost
  user: user
  password: change_me   # Здесь вы показываете структуру, но без настоящих значений

Добавляйте .gitignore в репозиторий как можно раньше

Лучший момент, чтобы создать .gitignore — перед первым коммитом. Тогда вы:

  • не затащите в репозиторий мусор;
  • не будете тратить время на «очистку» истории.

Если вы создаете проект через GitHub или GitLab, там часто уже предлагается выбрать шаблон .gitignore для соответствующего языка.

Будьте аккуратны с слишком общими шаблонами

Например, запись:

*.json

может скрыть из репозитория все JSON-файлы, включая важные конфиги, которые вы на самом деле хотели хранить в Git. Лучше указывать контекст:

logs/*.json           # Логи в формате JSON
tmp/**/*.json         # Временные JSON только в tmp

То же касается:

*.log
*.tmp
*.bak

Здесь лучше понимать, в каких каталогах они появляются, и при необходимости уточнять путь.

Старайтесь оставлять комментарии в .gitignore

Это поможет и вам, и другим участникам команды через пару месяцев понять, зачем добавлено то или иное правило.

Пример:

# Сборка фронтенда (генерируется Webpack)
dist/

# Кэш тестов Jest
coverage/

Заключение

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

Чтобы использовать .gitignore эффективно, важно понимать:

  • где он может находиться (локальный, глобальный, .git/info/exclude);
  • как работает синтаксис шаблонов (звездочки, вопросительные знаки, слэши, **);
  • как отменять игнорирование с помощью !;
  • что .gitignore не влияет на уже отслеживаемые файлы и как их перестать отслеживать.

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

Частозадаваемые технические вопросы по .gitignore

1. Как игнорировать все файлы в каталоге, кроме одного типа или конкретного файла?

Если вам нужно игнорировать все, кроме, например, .md файлов:

docs/*
!docs/*.md

Комментарии:

docs/*      # Игнорируем все в каталоге docs
!docs/*.md  # Но разрешаем Markdown файлы

Если нужно оставить один конкретный файл:

config/*
!config/
!config/main.yml

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

2. Как временно прекратить действие .gitignore для проверки?

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

git ls-files --others -i --exclude-standard

Чтобы увидеть, что именно игнорируется.
А чтобы просто игнор на время «выключить» без правки файлов, типичного флага нет, но вы можете:

  1. Временно переименовать .gitignore:

    mv .gitignore .gitignore.bak
    
  2. Выполнить нужные команды (git status, git add).
  3. Вернуть файл:

    mv .gitignore.bak .gitignore
    

3. Почему .gitignore не работает для подмодулей Git submodule?

Подмодуль — это отдельный репозиторий внутри другого репозитория. .gitignore родительского репозитория не управляет содержимым подмодуля. Чтобы игнорировать файлы внутри подмодуля, нужно:

  1. Зайти в каталог подмодуля.
  2. Создать или отредактировать его собственный .gitignore.
  3. Закоммитить изменения в репозиторий подмодуля.

4. Как игнорировать файлы только для merge-конфликтов (например, локальный конфиг)?

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

  1. В .gitattributes:

    config.local merge=ours
    
  2. Настраиваете стратегию ours:

    git config merge.ours.driver true
    

Теперь при merge Git всегда будет оставлять вашу локальную версию config.local, не пытаясь сливать изменения.

5. Можно ли условно игнорировать файлы в зависимости от ветки?

Сам .gitignore не поддерживает условия по веткам. Но можно использовать разные подходы:

  • хранить разные .gitignore в разных ветках;
  • использовать локальный .git/info/exclude для специфики вашей текущей работы;
  • применять скрипты-хуки, которые подменяют .gitignore при переключении веток.

Прямой механики «если ветка такая, игнорируй это» в .gitignore нет, поэтому обычно выбирают один из обходных путей в зависимости от сценария.

Стрелочка влевоПросмотр изменений в Git с помощью git diffСоздание коммита в Git - git commitСтрелочка вправо

Постройте личный план изучения Git до уровня Middle — бесплатно!

Git — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Git

Открыть базу знаний

Лучшие курсы по теме

изображение курса

Основы Git

Антон Ларичев
AI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий