Learning Platform
Глоссарий Troubleshooting
Урок 15.02 · 18 мин
Начальный
GitgitignoreGitHubdebugging

Шаблоны .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 и так далее.

Структура github/gitignore
root/
Global/
community/

Идея простая: один файл на язык/фреймворк, регулярно обновляется 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
TIP

Альтернатива без 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 отсутствует — значит не игнорируется
TIP

Привычка: когда .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
# (пусто)
DANGER

Если в .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-ов:

Антипаттерны .gitignore
IDE configs в repo
.env.example скрыт
logs/ забыт
абсолютные пути

Особенно важно: не клади в 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”. Запомни два правила:

  1. .gitignore действует только на untracked файлы. Tracked игнорируются после git rm --cached.
  2. Удаление из индекса не удаляет из истории. Если секрет утёк — ротация + filter-repo, см. модуль 18.

pip и venv: какие артефакты не нужно коммитить
Проверка знанийKnowledge check
Ты добавил `data/raw/` в .gitignore, но `git status` всё равно показывает `data/raw/dataset.csv` как modified. Какой алгоритм debugging?
ОтветAnswer
Алгоритм такой: (1) `git check-ignore -v data/raw/dataset.csv` — если показывает паттерн, значит правило работает, но файл уже tracked. Если молчит — паттерн не матчит, проверяй синтаксис. (2) `git ls-files --ignored --exclude-standard` — покажет, какие файлы и tracked, и подпадают под .gitignore. Если файл там есть — нужно `git rm --cached data/raw/dataset.csv` чтобы убрать из индекса. (3) После `git rm --cached` + commit файл перестанет отслеживаться, и .gitignore начнёт работать. Главный gotcha: `git rm --cached` не удаляет файл из старых коммитов — если там были секреты, нужна очистка истории через `git filter-repo` (модуль 18).

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. Где находится канонический источник .gitignore шаблонов?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4