Ключевые различия .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
- Что такое .gitkeep и почему он появился
- Ключевые различия между .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>→ добавьте правило в.gitignore→git 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‑файлы.
Источники
- Официальная документация Git (формат .gitignore)
- GitHub — Ignoring files (руководство)
- Генератор шаблонов .gitignore (gitignore.io / Toptal)
Заключение
.gitignore и .gitkeep — это не одинаковые вещи: .gitignore — официальный механизм для исключения файлов и папок, .gitkeep — простое соглашение для сохранения пустой директории в репозитории. На практике: используйте .gitignore для артефактов и секретов, а .gitkeep (или README) — для гарантированного наличия нужной структуры каталогов; и зафиксируйте выбранный подход в проектной политике, чтобы избежать путаницы.