Программирование

Ключевые различия .gitignore и .gitkeep в Git

Разбираем, в чём разница между .gitignore и .gitkeep в репозиториях Git. .gitignore игнорирует файлы и папки, .gitkeep сохраняет пустые директории. Примеры, ошибки и лучшие практики использования файлов gitignore и gitkeep.

В чём ключевые различия между файлами .gitignore и .gitkeep в репозиториях Git? Эти файлы выполняют одну и ту же функцию, но с разными названиями, или у них действительно разные назначения? У меня возникают трудности с поиском документации, специально посвящённой .gitkeep.

.gitignore — это файл, который указывает Git, какие файлы и папки не индексировать; файл gitignore обычно содержит шаблоны типа node_modules/, *.log, .env. .gitkeep — неофициальный файл‑маркер: пустой файл, который добавляют в пустую директорию, чтобы Git «видел» и сохранял эту папку в репозитории. Иначе говоря, .gitignore и .gitkeep решают разные задачи: один — исключает, другой — помечает/сохраняет структуру каталогов.


Содержание


Что такое .gitignore и зачем нужен файл .gitignore

.gitignore — встроенный механизм работы Git: это текстовый файл с шаблонами, по которым Git пропускает (не добавляет) файлы и каталоги при операциях индексации. Формат прост: строки — шаблоны, # — комментарий, ! — отмена шаблона, слэш в конце обозначает каталог. Примеры типичных записей:

# игнорировать каталоги и файлы
node_modules/
venv/
*.log
.env
.DS_Store

Зачем это нужно? Чтобы в репозиторий не попадали временные артефакты, зависимости, файлы окружения с секретами и т.д. Подробнее о формате и поведении см. в официальной документации Git: официальная документация Git и в справочнике GitHub по игнорированию файлов: руководство GitHub по игнорированию файлов.

Как добавить .gitignore и что важно учесть:

  • Создайте файл .gitignore в корне репозитория и добавьте шаблоны.
  • Если файл уже был добавлен в индекс до появления .gitignore, он не перестанет отслеживаться автоматически: используйте
    git rm --cached <путь/до/файла> и затем git commit.
  • Для быстрых шаблонов можно воспользоваться генератором шаблонов: генератор .gitignore (gitignore.io).

Что такое .gitkeep и почему он появился

.gitkeep — это просто соглашение, а не специальная функциональность Git. Git отслеживает файлы, но не саму структуру пустых папок: пустая папка без файлов не попадёт в коммит. Чтобы «застраховать» пустую директорию (например, папку для логов, временных файлов или загрузок), разработчики кладут в неё пустой файл — обычно с именем .gitkeep.

Пример использования:

mkdir -p logs
touch logs/.gitkeep
git add logs/.gitkeep
git commit -m "Add logs dir placeholder"

Альтернативы .gitkeep:

  • Положить в папку README.md с объяснением, зачем папка нужна — полезно, если хотите документировать назначение.
  • Использовать .gitignore внутри папки с содержимым:
*
!.gitignore

Такой .gitignore игнорирует всё в папке, но сохраняет сам файл .gitignore, поэтому папка попадёт в репозиторий. Но это немного запутанно по смыслу — .gitignore предназначен для исключения, а не для «сохранения» структуры.

Важно: у Git нет официальной инструкции по .gitkeep — это просто общеупотребительное имя. Можно использовать любое имя-файл, главное — договориться в команде.


Ключевые различия между .gitignore и .gitkeep

  • Назначение:
  • .gitignore — объявляет шаблоны файлов/папок, которые Git должен игнорировать (не добавлять в индекс).
  • .gitkeep — placeholder, который добавляют в пустую папку, чтобы сохранить её в репозитории.
  • Понимание Git:
  • .gitignore распознаётся Git и влияет на поведение git add.
  • .gitkeep — просто обычный файл; Git никак не интерпретирует его имя.
  • Влияние на уже отслеживаемые файлы:
  • .gitignore не снимет автоматом трекинг с уже закоммиченных файлов (нужно git rm --cached).
  • .gitkeep, будучи файлом в индексе, делает папку «нет пустой» — и папка остаётся в репозитории.
  • Семантика для команды:
  • .gitignore сообщает, что нельзя класть (build-артефакты, секреты).
  • .gitkeep — сигнал: «эта папка нужна, здесь будет что-то в runtime».

Коротко: они не взаимозаменяемы хотя иногда обе техники применяются для управления структурой проекта.


Практические примеры: игнорирование папок и сохранение пустых директорий

Игнорирование популярных папок:

# в .gitignore (корень репозитория)
node_modules/
build/
dist/
venv/
*.pyc
.env

Если .gitignore «не работает» (файлы продолжают попадать в репозиторий), обычно причины такие:

  • Файл уже был закоммичен до добавления в .gitignore — исправляется командой:
    git rm --cached path/to/file && git commit -m "Stop tracking file"
  • Неправильный шаблон или расположение .gitignore (шаблоны относительные к месту .gitignore).
  • У вас есть глобальный exclude (git config --global core.excludesfile) или .git/info/exclude, которые влияют на поведение.

Сохранение пустой директории:

  • Самый простой способ — положить файл .gitkeep (или README.md) в папку и закоммитить.
  • Если команда предпочитает не иметь служебных файлов, можно использовать README с объяснением, зачем нужна папка — это и документация, и гарантия того, что папка будет в репозитории.

Рекомендации:

  • Используйте .gitignore для исключения артефактов и чувствительных данных.
  • Для пустых директорий используйте .gitkeep или README.md — договоритесь об одном варианте в команде.
  • Добавляйте в коммит сообщение с пояснением, зачем создан .gitkeep (чтобы не было вопросов потом).

Частые ошибки и как их исправить

  • Проблема: .gitignore не действует на уже закоммиченные файлы.
    Решение: git rm --cached <file> → добавьте правило в .gitignoregit commit.
  • Проблема: забыли закоммитить .gitkeep, папка не появилась.
    Решение: проверьте, не попадает ли имя .gitkeep под глобальные исключения, и закоммитьте файл.
  • Проблема: команда использует разные подходы (кто‑то .gitkeep, кто‑то .gitignore с исключениями).
    Решение: зафиксируйте правило в CONTRIBUTING/README или настройках проекта.
  • Проблема: по шаблону не игнорируется подпапка.
    Решение: проверьте синтаксис (слеш в конце для папок, ! для отмены) и расположение .gitignore.

Короткий чеклист при проблемах:

  • Убедитесь, что файл действительно не в индексе (git ls-files | grep <имя>).
  • Если нужно — очистите кэш: git rm -r --cached . и затем git add . && git commit -m "Refresh .gitignore rules".
  • Проверьте глобальные и локальные exclude‑файлы.

Источники


Заключение

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

Авторы
Проверено модерацией
Модерация