Удаляем случайно закомиченные приватные данные из git репозитория
Однажды, работая с git репозиторием вы можете случайно отправить (закомитить) в репозиторий свои личные логины, пароли или SSH ключи. Конечно, с помощью git rm
можно удалить файл, но файл так же будет присутствовать в истории. К счастью есть утилиты которые позволяют удалить файл из git репозитория полностью. В это статье описано как использовать BFG Repo-Cleaner и git-filter-branch для полного удаления файла из git репозитория.
Важно: после того, как файл с приватными данными попал в репозиторий, все данные в нем можно считать скомпроментированными, и необходимо незамедлительно предпринять меры (поменять пароли, и т.д.). Нет возможности проследить успел ли кто либо посмотреть или скачать эти файлы.
git-filter-branch
Начать пожалуй стоит с git-filter-branch
, так как эта утилита является частью git и не требует установки.
Переходим в директорию с нужным проектом:
cd {GIT_PROJECT_LOCATION}
Первое что нужно сделать - это убедится, что у нас самая последняя версия репозитория и нет никаких локальных изменений.
bash:~$ git status
On branch master
nothing to commit, working directory clean
bash:~$ git pull origin master
From bitbucket.org:bosha/test-repo
* branch master -> FETCH_HEAD
Already up-to-date.
bash:~$
Предположим, что мы случайно закомитили в репозиторий файл .environment
в котором у нас храниться пароль к базе данных. Проект в активной разработке и испольуется тестовая база данных, но по привычке пароль использовали такой же какой для входа в систему или ещё куда либо. Знакомая ситуация? :)
После того, как мы убедились что у нас последняя версия и отсутствуют локальные изменений, можно удалять файл:
bash:~$ git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch .environment' \
--prune-empty --tag-name-filter cat -- --all
Rewrite d402133542d0f0f1578e916b8a350842cc955870 (4/4) (0 seconds passed, remaining 0 predicted) rm '.environment'
Ref 'refs/heads/master' was rewritten
Ref 'refs/remotes/origin/master' was rewritten
В результате выполнения этой команды, в каждом коммите репозитория будет удален файл .environment
. Если необходимо удалить директорию, то к git rm
необходимо добавить ключ -f
:
bash:~$ git filter-branch --force --index-filter \
'git rm -f --cached --ignore-unmatch {DIRETORY_TO_REMOVE}/' \
--prune-empty --tag-name-filter cat -- --all
Если есть ещё файлы которые необходимо удалить - выполняете эту команду для каждого из них.
Важно: дабы избежать повторения этой неприятной ситуации, файл необходимо добавить в .gitignore
:
echo ".environment" >> .gitignore
git add .gitignore
git commit -m '.environment was added to .gitignore'
Теперь закомитим все наши изменения:
git push origin --force --all
Если использовали теги:
git push origin --force --tags
Важно: после всех проделанных изменений всем остальным кто работал с этим репозиторием, необходимо сделать rebase. Либо удалить свой локальный репозиторий и склонировать его ещё раз. Лучше последнее, так как меньше шансов выстрелить себе в ногу, особенно если в команде есть джуны. :)
BFG Repo-Cleaner
BFG Repo-Cleaner
- это более простая и легкая альтернатива git-filter-branch
для удаления нежелательных файлов из git репозитория. Например, чтобы удалить файл .environment
как в примере с git-filter-branch
выше:
bfg --delete-files .environment
BFG даже может просмотреть все файлы в репозитории на наличие паролей и заменить их на **REMOVED**
:
bfg --replace-text my_passwords.txt`
В результате выполнения этой команды, каждый файл в каждом коммите будет просмотрен и если в нем будет найден пароль из файла my_passwords.txt
, то он будет заменен на **REMOVED**
.
Выводы
Несмотря на то, что файл и возможно удалить после случайного коммита, этого следует избегать. Есть несколько простых вещей которые стоит избегать, и наоборот использовать:
- Использовать программы с графическим интерфейсом для работы git. Они наглядно показывают какие файлы будут добавлены в коммит. Во всех средах разработки как правило есть либо дополнения, либо встроенные средства для работы с git которые помогают избежать таких ошибок. Если среда разработки которую вы используете не имеет средств работы с git, то есть графические интерефейсы. Я когда-то писал небольшой обзор графических интерфейсов для git;
- Избегать таких опасных команд как
git add .
,git add -A
иgit commit -a
. Вместо них добавлять отдельные файлы сgit add {filename}
; - Использовать
git add --interactive
чтобы интерактивно просматривать и добавлять файлы; - Перед добавлением файлов внимательно просматривать какие файлы были изменены и могут попасть в коммит
git status
.
Полезные ссылки: