Все главы учебника
Содержание учебника
Глава 13 / Git

Ignore, секреты и большие файлы: границы публикации

18 мин чтенияКонтент v0.10.0

Лишний файл появился в подготовке

В папке проекта есть настройки, локальный журнал и результат сборки. Исходники нужны всем, журнал — только текущему запуску, а личные данные нельзя превращать в содержимое общей истории. Git не понимает смысл каждого файла. Нужно заранее определить, что является частью проекта, проверить подготовленный diff и настроить правила исключения.

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

В этой главе используем только строку TRAINING_ONLY_NOT_A_SECRET. Не подставляйте настоящий пароль, токен или приватный ключ ради опыта. Нам нужно увидеть достижимость старого содержимого, а не создать реальную проблему доступа. Умение объяснить ограничение проверяется на синтетическом файле так же хорошо.

Сохраните учебную ошибку и исправьте текущее дерево

lab=$(mktemp -d "${TMPDIR:-/tmp}/git-13.XXXXXX")
cd "$lab"
git init -b main
git config user.name "Учебный автор"
git config user.email "learner@example.invalid"
git config commit.gpgsign false
printf 'TOKEN=TRAINING_ONLY_NOT_A_SECRET\n' > .env
printf 'TOKEN=replace-locally\n' > .env.example
printf 'Project\n' > README.txt
git add .env .env.example README.txt
git commit -m "Record deliberately fake training configuration"
first=$(git rev-parse HEAD)
printf '.env*\n!.env.example\n*.log\n/build/\n' > .gitignore
printf 'local event\n' > app.log
mkdir build
printf 'generated\n' > build/output.txt
git status --short
git check-ignore -v app.log build/output.txt
git rm --cached .env
git add .gitignore
git commit -m "Stop tracking local configuration"
git ls-files
cat .env
git show "$first":.env

В текущем списке tracked нет .env, но файл остаётся на диске. Исторический show всё ещё выводит фиктивную строку. rm --cached убрал путь из индекса и нового снимка, не стёр все прежние версии. .env.example остаётся в проекте благодаря исключению из шаблона. Новые журналы и build/output.txt не предлагают обычному add.

Если .env уже отслеживается, check-ignore без дополнительных опций может не показывать его как исключённый: игнорирование не предназначено для существующих tracked-путей. Для диагностики модели можно использовать git check-ignore --no-index -v .env. В наших командах сначала изучаем новый журнал, чтобы не смешивать эти два случая.

Что делать при настоящей утечке

Если действующий секрет уже опубликован, в первую очередь отзовите или смените его у поставщика доступа. Удаление файла новым коммитом не делает старый ключ безопасным. Затем определяют, где появились копии, и согласуют очистку истории с владельцами репозитория. Даже после переписывания могут оставаться клоны, кэши и ссылки. Официальная инструкция GitHub объясняет эти ограничения и порядок действий.

В первом курсе мы не переписываем общую историю и не выполняем force push ради демонстрации очистки. Правильная учебная цель — предотвратить сохранение, отличать текущий снимок от всей истории и не выдавать удаление за отзыв доступа. Сканер секретов полезен, но не освобождает от проверки файлов: произвольные личные данные могут не иметь узнаваемого шаблона.

Большой файл и переносы строк

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

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

Для обычного текста можно договориться о переносах строк через .gitattributes, например *.txt text eol=lf. Это правило относится к нормализации текстовых путей, а не игнорированию. Перед применением к существующему проекту просмотрите возникающий diff: изменение формата может затронуть много строк без изменения смысла. Gitattributes позволяет проверить детали без изменения глобальных настроек.

Проверьте набор публикации

Перед новым коммитом прочитайте не только ignore, но и список подготовленных путей. Правило может быть верным, а лишний файл — уже отслеживаться. В своей лаборатории покажите оба наблюдения: check-ignore объясняет шаблон, cached diff показывает реальное предложение снимка. Если они кажутся противоречивыми, сначала спросите, был ли путь tracked раньше.

Для больших файлов запишите, кто и как получит содержимое: обычный Git-объект, внешний LFS-объект или ссылка на отдельный артефакт. Указатель без работающего способа доставки не делает проект воспроизводимым. Это вопрос состава проекта, а не соревнование размеров репозитория. Обязательный текстовый курс позволяет изучить границу бесплатно и без загрузки чужих данных.

Самостоятельная лаборатория

Практика — 35–50 минут. В новом репозитории создайте игнорируемый журнал, локальный фиктивный конфиг, публичный example и папку сборки. Сначала настройте ignore, затем добавьте только необходимые пути. Проверьте ls-files и cached diff до первого commit. Убедитесь, что example остаётся видимым, а локальные файлы существуют на диске без отслеживания.

Отдельно повторите опыт с ранее сохранённым фиктивным конфигом. Покажите его отсутствие в новом снимке и присутствие в старом. Напишите ответ на два вопроса: что надо сделать первым при настоящей утечке и какие дополнительные объекты нужны клону с LFS-указателем.

Критерии готовности

Вы не путаете ignore, снятие отслеживания и удаление истории. Лаборатория не содержит настоящего секрета, пример настроек опубликован, журнал и сборка исключены. Старое содержимое остаётся читаемым ожидаемо. Ваш ответ начинается с отзыва действующего доступа, а не с обещания «Git всё забыл».

Разбор

Если example тоже исчез из списка, проверьте порядок шаблонов и знак отрицания. Если журнал попал в историю, посмотрите, не был ли он tracked до ignore или добавлен принудительно. Следующий этап — финальный проект, где эти правила станут частью критериев командной работы.