Редакция в Git - PullRequest
       1

Редакция в Git

14 голосов
/ 21 января 2010

Я недавно начал работать над небольшим скриптом Python для FTP. Для начала у меня были данные сервера, логина и пароля для FTP-сайта, встроенные в сценарий, но это не имело значения, потому что я работал над ним только локально.

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

Вопрос в том, есть ли способ просмотреть историю мерзавцев и полностью удалить имя пользователя и пароль, но в противном случае оставить историю нетронутой? Или мне нужно начать новый репо без истории?

Ответы [ 4 ]

23 голосов
/ 21 января 2010

Прежде всего, вам необходимо сменить пароль на FTP-сайте. Пароль уже обнародован; Вы не можете гарантировать, что никто не клонировал репозиторий, или он не находится в виде простого текста в резервной копии где-либо, или что-то в этом роде. Если пароль вообще ценный, я бы посчитал его взломанным.

Теперь, на ваш вопрос о том, как редактировать историю. Команда git filter-branch предназначена для этой цели; он будет проходить каждый коммит в истории вашего репозитория, применять команду для его изменения, а затем создавать новый коммит.

В частности, вы хотите git filter-branch --tree-filter. Это позволяет редактировать содержимое дерева (фактические файлы и каталоги) для каждого коммита. Он будет запускать команду в каталоге, содержащем все дерево, ваша команда может редактировать файлы, добавлять новые файлы, удалять файлы, перемещать их и так далее. Затем Git создаст новый объект фиксации со всеми теми же метаданными (сообщение коммита, дата и т. Д.), Что и предыдущий, но с деревом, измененным вашей командой, обработав новые файлы как добавления, пропущенные файлы как удаления, и т.д. (поэтому вашей команде не нужно делать git add или git rm, просто нужно изменить дерево).

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

git filter-branch --tree-filter "sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py" -- --all

Не забудьте сделать это с копией вашего хранилища, поэтому, если что-то пойдет не так, у вас все равно будет оригинал, и вы сможете начать все заново. filter-branch также сохранит ссылки на ваши исходные ветки, как original/refs/heads/master и т. Д., Поэтому вы сможете восстановить, даже если вы забудете это сделать; делая глобальные изменения в моей истории исходного кода, я хотел бы убедиться, что у меня есть несколько откатов на случай, если что-то пойдет не так.

Чтобы объяснить, как это работает более подробно:

sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py

Это заменит SekrtPassWrd в вашем myscript.py файле на REDACTED; опция -i для sed говорит, что он должен редактировать файл на месте, без файла резервной копии (так как Git выберет эту резервную копию как новый файл).

Если вам нужно сделать что-то более сложное, чем одиночная замена, вы можете написать скрипт и просто вызвать его для своей команды; просто обязательно вызывайте его с абсолютным путем, так как git filter-branch вызывает вашу команду из временного каталога.

git filter-branch --tree-filter <command> -- --all

Это говорит git запускать древовидный фильтр, как описано выше, для каждой ветви в вашем хранилище. Часть -- --all говорит Git применить это ко всем веткам; без него он только отредактировал бы историю текущей ветви, оставив все остальные ветви без изменений (что, вероятно, не то, что вам нужно).

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

5 голосов
/ 21 января 2010

Может, просто проще сменить пароль на FTP-сайте? Если вы не смущены кодом ...

3 голосов
/ 21 января 2010

Полагаю, вы сможете изменить все свои коммиты с помощью команды filter-branch. Подробнее см. в разделе книги ProGit .

Однако, как примечание ссылки @ MBO

принудительное нажатие не стирает коммиты на удаленном репо, оно просто вводит новые и перемещает указатель ветви, чтобы указывать на них

Таким образом, вам нужно полностью удалить репозиторий из GitHub, чтобы удалить эти коммиты (т. Е. Даже если они не в вашей истории коммитов, они все еще плавают в репозитории)

1 голос
/ 31 декабря 2017

Чтобы добавить к выбранному ответу от @ Brian Campbell , у меня были проблемы с его кодом в моем случае использования. Я просто пропустил рассматриваемый файл в предыдущих коммитах. Я уверен, что я не единственный человек в этой ситуации, поэтому я сделал простое исправление / взлом

git filter-branch --tree-filter "sed -i -e 's/SekrtPassWrd/REDACTED/' myscript.py || echo 'fail'" -- --all

Все, что я сделал, это добавил || echo 'fail', чтобы код продолжал работать, даже если файл не был найден в коммите. Я надеюсь, что кто-то еще найдет это полезным или может ответить с лучшим методом обработки отсутствующих файлов. У меня недостаточно репутации, поэтому мне пришлось сделать новый ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...