Вечный покой .env: как эффективнее удалять закомиченный файл .env из Git-репозитория

Всем барев дзес! На связи Гагик Антонян. Я — Frontend-разработчик и это моя первая статья на Хабре. Сегодня вы узнаете, как полноценно удалять .env, который по ошибке попал на удаленный Github-репозиторий. Буду рад, если поддержите данный материал лайками и комментариями. А теперь погнали рвать пределы IT-галактики.

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

Я работаю на VS Code, и я, to be honest, так и не понял, с какой стати .gitignore "не игнорирует" .env. Причем спокойно "игнорирует" другие файлы, директории.

Всё же, нужно действовать, исходя из конкретного кейса, но если вы не хотите, чтобы какой-нибудь John Doe воспользовался данными из вашего .env, то вы перешли по верной ссылке. Вы же не отдаете ключи грабителю с фразой "Грабьте мой дом", верно? Точно так же и тут. Поэтому я предлагаю потихоньку начать.


Шаг 1: Создание проекта

В этом шаге я создам приложение от Next.js. С этим проектом я буду работать на VS Code. Осуществляю создание Next.js-проекта через пакетный менеджер pnpm.

pnpm dlx create-next-app@latest kill-env

После того, как я задал настройки в терминале, как будет выглядеть проект (в статье это не важно от слова совсем), перейдем к коду. Но перед этим я хочу связать проект с удаленным репозиторием Github. Итоговую кодовую базу можно увидеть на картинке.

Готовый проект в VS Code

Шаг 2: Подключение локального проекта с Github-репозиторием.

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

P.S.: Я не буду здесь прописывать и так ясные команды для осуществления связки, поэтому результат представлен на картинке.

Репозиторий, откуда могут быть "сюрпризы"
Репозиторий, откуда могут быть "сюрпризы"

Шаг 3: Разбор кейса и его решение

3.1 В какую проблему можно попасть из-за невнимательности

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

Для приличия моего коммита я практически полностью удалил код разметки в одном из файлов моего проекта. Сюр в том, что на уделённый репозиторий залился и .env файл вместе с остальными изменениями. Как не должно быть в вашем репозитории показан на картинке:

Мои "поздравления", секретный файл теперь уже не секретный...
Мои "поздравления", секретный файл теперь уже не секретный...

Да, .gitignoreфайл не отменяет уже зафиксированные изменения (поэтому название папки зависимостей проекта закрашен в серый цвет но не несчтастный .env. Это можно увидеть на приложенной картинке. И так, как мы можем это исправить?

Да, на это очень больно смотреть...
Да, на это очень больно смотреть...

3.2 Решение проблемы

Для начала воспользуемся следующей командой:

git rm -r --cached .env
Последствие выполнения команды git rm -r --cached .env
Последствие выполнения команды git rm -r --cached .env

Не бойтесь, мы удаляем файл .env и все его подпапки из области подготовки Git, но не из самой файловой системы проекта. Внеся изменения мы увидим, что .env больше не числится в списках файлов проекта.

А где? где ты, .env?

Если вы думаете, что это happy end, то спешу разочаровать: это ещё не конец. Перейдя на историю коммитов можно обнаружить интересную вещь: хоть мы удалили файл из корневой директории проекта, данные из файла .env как были в истории, так и остались. Не верите? Показываю это на картинке:

Просчитался, но где, ара?
Просчитался, но где, ара?

Пришло время раз и навсегда расправиться с этой проблемой. Вводим следующую команду, которая удаляет все файлы и папки с именем .env из истории коммитов текущей ветки (HEAD):

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch .env" HEAD

В ответ получим несколько предупреждений о том, что это испортило нашу историю, поскольку это пройдет через всю нашу историю и на 100% устранит ее существование. Чтобы это сделать, нужно выполнить следующую команду.

git push --force

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

Миссия выполнена
Миссия выполнена

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

До скорых встреч!