Шаблоны .gitignore: GitHub, gh gist и debugging
Писать .gitignore с нуля для каждого проекта — это бесполезная работа. Тысячи людей до тебя уже писали “игнор для Python”, “игнор для Node.js”, “игнор для macOS”. GitHub собрал эти шаблоны в один публичный репо, и каждый раз когда ты создаёшь репозиторий через UI, GitHub предлагает выбрать шаблон.
В этом уроке: где брать готовые шаблоны, как их быстро вставить через gh CLI, как комбинировать несколько (Python + Jupyter + macOS), и как дебажить .gitignore через git check-ignore и git ls-files, когда что-то не работает.
github/gitignore: каноничный источник
Репо github.com/github/gitignore — это публичная коллекция шаблонов. В нём около 200 файлов вида Python.gitignore, Node.gitignore, Go.gitignore, Rust.gitignore и так далее.
Идея простая: один файл на язык/фреймворк, регулярно обновляется community, проверен тысячами проектов. Когда стартуешь новый Python-проект — берёшь Python.gitignore, комбинируешь с Global/macOS.gitignore и community/JupyterNotebooks.gitignore. Готово.
Способ 1: GitHub UI при создании репо
Когда ты создаёшь репо через github.com/new, в форме есть dropdown “Add .gitignore” с тем же списком шаблонов. Выбираешь Python — GitHub автоматически создаст в репо .gitignore с содержимым Python.gitignore.
Это самый простой способ для нового проекта. Но у него ограничение: можно выбрать только один шаблон. Если нужно Python + macOS + Jupyter — придётся вручную доклеивать.
Способ 2: gh gist gitignore
GitHub CLI имеет extension для удобной работы с шаблонами. Через расширение gh-gitignore (или просто copy с github.com/github/gitignore):
# Установить расширение (один раз)
gh extension install hectcastro/gh-gitignore
# Получить шаблон Python в текущую директорию
gh gitignore set Python > .gitignore
# Скомбинировать несколько (просто конкатенация)
gh gitignore set Python > .gitignore
gh gitignore set Global/macOS >> .gitignore
gh gitignore set community/JupyterNotebooks >> .gitignore
Альтернатива без gh extension: просто curl напрямую из raw.githubusercontent.com.
# Прямой curl — работает всегда
curl -fsSL https://raw.githubusercontent.com/github/gitignore/main/Python.gitignore > .gitignore
curl -fsSL https://raw.githubusercontent.com/github/gitignore/main/Global/macOS.gitignore >> .gitignore
curl -fsSL https://raw.githubusercontent.com/github/gitignore/main/community/JupyterNotebooks.gitignore >> .gitignore
Или ещё проще — сервис gitignore.io (он же toptal.com/developers/gitignore):
# Скомбинировать сразу несколько шаблонов через API
curl -fsSL "https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks,macos,vscode,linux" > .gitignore
Это вернёт один файл, где аккуратно собраны все указанные шаблоны с заголовками-комментариями. Удобно для быстрого старта.
Способ 3: copy-paste из GitHub UI
Самый прямолинейный — открыть https://github.com/github/gitignore, найти нужный файл, нажать “Raw”, скопировать содержимое.
Это полезно когда:
- Нет интернета в CLI окружении (например, корпоративный proxy)
- Нужно сразу глазами посмотреть, что внутри, и адаптировать
Hands-on: собрать .gitignore для Python DE проекта
Возьмём пример Python ETL с Jupyter и DBT:
# Создаём новый репо
mkdir my-de-project && cd my-de-project
git init
# Скачиваем шаблоны через gitignore.io
curl -fsSL "https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks,macos,vscode,linux,dbt" > .gitignore
# Смотрим, что получилось
head -30 .gitignore
Вывод (сокращённо):
# Created by https://www.toptal.com/developers/gitignore/api/python,jupyternotebooks,...
### Python ###
__pycache__/
*.py[cod]
*$py.class
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
...
### JupyterNotebooks ###
.ipynb_checkpoints
*/.ipynb_checkpoints/*
...
### macOS ###
.DS_Store
.AppleDouble
...
Дальше — добавляем специфику нашего проекта:
# Дописываем то, что специфично для нашего ETL
cat >> .gitignore <<'EOF'
### Project-specific ###
# Секреты
.env
.env.local
!.env.example
# Данные
data/raw/
data/interim/
data/processed/
!data/**/README.md
# Локальные дампы
*.duckdb
*.sqlite
*.parquet
# Airflow
airflow.db
airflow.cfg
EOF
Commit:
git add .gitignore
git commit -m "chore: add .gitignore for Python ETL project"
Получаешь готовый стартовый .gitignore за минуту, не написав сам ни строки.
git check-ignore: главный debug-инструмент
Самая частая фраза джуна: “Я добавил файл в .gitignore, а Git его всё равно видит”. git check-ignore -v <file> — твой друг.
# Базовое использование — какое правило игнорирует файл
$ git check-ignore -v data/raw/dataset.csv
.gitignore:42:data/raw/ data/raw/dataset.csv
# Файл НЕ игнорируется — пустой output
$ git check-ignore -v src/main.py
# (тишина)
$ echo $?
1 # exit code 1 = не игнорируется
Структура вывода: <source>:<line>:<pattern> <file>.
source— какой.gitignoreсработал (может быть и global, и repo, и subdir)line— на какой строке этого файла лежит правилоpattern— собственно сам паттерн
Это бесценно когда правил много. Особенно когда подключены global и subdir .gitignore — без -v ты не поймёшь, кто матчит.
# Несколько файлов сразу
$ git check-ignore -v data/raw/a.csv data/processed/b.parquet src/main.py
.gitignore:42:data/raw/ data/raw/a.csv
.gitignore:44:data/processed/ data/processed/b.parquet
# src/main.py отсутствует — значит не игнорируется
Привычка: когда .gitignore “не работает” — первая команда git check-ignore -v <file>. Не “печатать .gitignore руками и искать паттерн глазами”. CLI делает это за тебя точно.
git ls-files: какие файлы УЖЕ отслеживаются
Другой угол: .gitignore не работает на уже tracked файлы. То есть если ты случайно закоммитил .env, добавление его в .gitignore ничего не изменит — .env уже в индексе.
git ls-files покажет, что сейчас отслеживается:
# Все tracked файлы
$ git ls-files
.gitignore
README.md
src/main.py
# Только те, которые matched-бы .gitignore (но всё равно tracked — баг!)
$ git ls-files --ignored --exclude-standard
.env ← УПС, закоммитили .env, теперь надо чистить
Если git ls-files --ignored --exclude-standard показывает файлы — это всегда проблема. Эти файлы матчат .gitignore, но всё равно отслеживаются Git-ом. Надо чистить:
# Убрать из индекса (но оставить в filesystem)
$ git rm --cached .env
$ git commit -m "chore: remove .env from tracking"
# Проверь, что чисто
$ git ls-files --ignored --exclude-standard
# (пусто)
Если в .env уже попали реальные секреты — git rm --cached НЕ удалит их из истории. Они останутся в старых коммитах, доступны через git log. Это тема модуля 18 — там разберём git filter-repo и BFG для очистки истории. Совет на сейчас: если секреты утекли в публичный репо — немедленно rotate-нуть пароли/токены.
git status —ignored: посмотреть, что Git скрывает
По умолчанию git status НЕ показывает игнорированные файлы — это удобно для повседневной работы. Но иногда полезно посмотреть, что Git замёл под ковёр:
$ git status --ignored
On branch main
Untracked files:
src/new_module.py
Ignored files:
.env
__pycache__/
data/raw/
.venv/
# Короткая форма
$ git status --ignored -s
?? src/new_module.py
!! .env
!! __pycache__/
!! data/raw/
!! .venv/
!! — маркер ignored файлов. Это полезно при code review своих изменений: “не игнорирую ли я что-то важное случайно?”.
Антипаттерны: что НЕ класть в .gitignore
Несколько частых ошибок junior-ов:
Особенно важно: не клади в repo .gitignore то, что специфично для твоей машины или IDE. Это засирает чужие .gitignore. Используй global для личного.
Попробуй сам: дебаг реального случая
Создадим ситуацию, которая ломает джунов:
mkdir debug-demo && cd debug-demo
git init
# Закоммитили .env (опечатка в команде)
echo "DB_PASSWORD=secret123" > .env
git add .env
git commit -m "oops, committed .env"
# Поздно понял — добавил в .gitignore
echo ".env" > .gitignore
git add .gitignore && git commit -m "add .env to gitignore"
# Изменили .env
echo "DB_PASSWORD=secret456" >> .env
# Git всё равно видит изменения!
git status
# modified: .env
# Проверь — игнорируется ли .env по правилам?
git check-ignore -v .env
# .gitignore:1:.env .env ← да, паттерн матчит
# Но он tracked!
git ls-files --ignored --exclude-standard
# .env ← вот в чём проблема
# Решение — убрать из индекса
git rm --cached .env
git commit -m "untrack .env"
# Теперь .env не tracked и игнорируется
git status
# nothing to commit, working tree clean
git ls-files --ignored --exclude-standard
# (пусто — чисто)
# Но! Если он был запушен — его уже видели коллеги.
# Секрет нужно ротировать, а историю чистить через filter-repo (модуль 18)
Этот сценарий — главная “ловушка .gitignore”. Запомни два правила:
.gitignoreдействует только на untracked файлы. Tracked игнорируются послеgit rm --cached.- Удаление из индекса не удаляет из истории. Если секрет утёк — ротация + filter-repo, см. модуль 18.
pip и venv: какие артефакты не нужно коммитить