Удаление конфиденциальных файлов и их коммитов из истории Git
Я хотел бы поместить проект Git на GitHub, но он содержит определенные файлы с конфиденциальными данными (имена пользователей и пароли, например /config/deploy.РБ для Капистрано).
Я знаю, что могу добавить эти имена файлов в .gitignore, но это не удалит их историю в Git.
Я также не хочу начинать все сначала, удалив /.каталог git.
есть ли способ удалить все следы конкретного файла в вашем Git история?
10 ответов:
для всех практических целей первый то, что вы должны беспокоиться о ИЗМЕНЕНИЕ ПАРОЛЕЙ! из вашего вопроса неясно, является ли ваш репозиторий git полностью локальным или у вас есть удаленный репозиторий в другом месте; если он удален и не защищен от других, у вас есть проблема. Если кто-то клонировал этот репозиторий до того, как вы это исправите, у них будет копия ваших паролей на их локальной машине, и вы не сможете заставить их чтобы обновить до вашей "исправленной" версии, когда она ушла из истории. Единственная безопасная вещь, которую вы можете сделать, это изменить свой пароль на что-то другое везде, где вы его использовали.
С этим из пути, вот как это исправить. GitHub ответил именно на этот вопрос в качестве FAQ:
Примечание для пользователей Windows: используйте двойные кавычки (") вместо одиночных в этой команде
git filter-branch --index-filter \ 'git update-index --remove filename' <introduction-revision-sha1>..HEAD git push --force --verbose --dry-run git push --force
имейте в виду, что как только вы нажали этот код удаленный репозиторий, такой как GitHub и другие, клонировал этот удаленный репозиторий, теперь вы находитесь в ситуации, когда вы переписываете историю. Когда другие пытаются снять ваши последние изменения после этого, они получат сообщение о том, что изменения не могут быть применены, потому что это не быстрая перемотка вперед.
чтобы исправить это, им придется либо удалить свой существующий репозиторий и повторно клонировать его, либо следовать инструкциям в разделе "Восстановление из восходящей РЕБАЗЫ" в git-rebase man-страницы.
в будущем, если вы случайно совершить некоторые изменения с конфиденциальной информацией, но вы заметите до нажав на удаленный репозиторий, есть несколько более простых исправлений. Если вы в последний раз фиксируете добавление конфиденциальной информации, вы можете просто удалить конфиденциальную информацию, а затем запустить:
git commit -a --amend
это изменит предыдущую фиксацию с любыми новыми изменениями, которые вы сделали, включая полное удаление файлов, выполненное с помощью
git rm
. Если изменения находятся дальше в истории, но все еще не перенесены в удаленный репозиторий, вы можете выполнить интерактивную перебазировку:git rebase -i origin/master
это открывает редактор с фиксациями, которые вы сделали с момента вашего последнего общего предка с удаленным репозиторием. Измените "pick "на" edit " в любых строках, представляющих фиксацию с конфиденциальной информацией, а также сохраните и завершите работу. Git пройдет через изменения и оставит вас в том месте, где вы можете:
$EDITOR file-to-fix git commit -a --amend git rebase --continue
для каждого изменения с конфиденциальная информация. В конце концов, вы вернетесь на свою ветку, и вы можете безопасно продвигать новые изменения.
изменение паролей-хорошая идея, но для процесса удаления пароля из истории вашего РЕПО я рекомендую BFG Repo-Cleaner, более быстрая и простая альтернатива
git-filter-branch
явно предназначен для удаления личных данных из Git РЕПО.создать
private.txt
файл со списком паролей и т. д., которые вы хотите удалить (по одной записи в строке) , а затем выполните следующую команду:$ java -jar bfg.jar --replace-text private.txt my-repo.git
все файлы с пороговым размером (1 МБ по умолчанию) в вашем история РЕПО будет сканироваться, и любая соответствующая строка (это не в вашем последний commit) будет заменена строкой "***REMOVED***". Затем вы можете использовать
git gc
чтобы убрать мертвые данные:$ git gc --prune=now --aggressive
BFG обычно в 10-50 раз быстрее, чем работает
git-filter-branch
и параметры упрощены и адаптированы вокруг этих двух общих случаев использования:
- удаление Сумасшедшие Большие Файлы
- удаление пароли, Учетные данные и другие личные данные
полное раскрытие информации: я автор BFG Repo-Cleaner.
рекомендую этот скрипт Дэвид Андерхилл, работал как шарм для меня.
Он добавляет эти команды в дополнение к фильтр-ветви natacado, чтобы очистить беспорядок, который он оставляет позади:
rm -rf .git/refs/original/ git reflog expire --all git gc --aggressive --prune
полный сценарий (все заслуга Дэвида Андерхилла)
#!/bin/bash set -o errexit # Author: David Underhill # Script to permanently delete files/folders from your git repository. To use # it, cd to your repository's root and then run the script with a list of paths # you want to delete, e.g., git-delete-history path1 path2 if [ $# -eq 0 ]; then exit 0 fi # make sure we're at the root of git repo if [ ! -d .git ]; then echo "Error: must run this script from the root of a git repository" exit 1 fi # remove all paths passed as arguments from the history of the repo files=$@ git filter-branch --index-filter \ "git rm -rf --cached --ignore-unmatch $files" HEAD # remove the temporary history git-filter-branch # otherwise leaves behind for a long time rm -rf .git/refs/original/ && \ git reflog expire --all && \ git gc --aggressive --prune
последние две команды могут работать лучше, если изменить их на следующие:
git reflog expire --expire=now --all && \ git gc --aggressive --prune=now
Если вы уже нажали на GitHub, данные будут скомпрометированы, даже если вы заставите оттолкнуть его через секунду потому что:
GitHub продолжает висеть фиксации в течение длительного времени.
персонал GitHub имеет право удалять такие оборванные коммиты, если вы свяжетесь с ними, однако, что вы должны сделать:Как удалить свисающий коммит из GitHub?
висячие коммиты можно увидеть либо через:
- веб-интерфейс фиксации: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( Wayback machine)
- API: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( Wayback machine)
один удобный способ получить источник при этом фиксации - использовать zip-файл загрузки метод, который может принять любую ссылку, например:https://github.com/cirosantilli/myrepo/archive/SHA.zip
можно получить недостающие ШАС либо:
- список событий API с
type": "PushEvent"
. Например, мой:https://api.github.com/users/cirosantilli/events/public ( Wayback machine)- более удобно иногда, глядя на ШАС pull запросов, которые пытались удалить содержание
есть скрапперы, как http://ghtorrent.org/ и https://www.githubarchive.org/ которые регулярно объединяют данные GitHub и хранят их в другом месте.
Я не мог найти, если они царапают фактический фиксации diff, но это технически возможно.
чтобы проверить это, я создал РЕПО:https://github.com/cirosantilli/test-dangling и сделано:
git init git remote add origin git@github.com:cirosantilli/test-dangling.git touch a git add . git commit -m 0 git push touch b git add . git commit -m 1 git push touch c git rm b git add . git commit --amend --no-edit git push -f
Если вы удалить репозиторий однако коммиты исчезают даже из API сразу и дают 404, например https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 это работает, даже если вы воссоздаете другой репозиторий с тем же именем.
поэтому мой рекомендуемый курс действий:
изменить учетные данные
если этого недостаточно (например, голые фото):
- удалить репозиторий
- обратитесь в службу поддержки
чтобы быть ясным: принятый ответ правильный. Попробуй сначала. Однако это может быть излишне сложным для некоторых случаев использования, особенно если вы сталкиваетесь с неприятными ошибками, такими как "fatal: bad revision --prune-empty", или действительно не заботитесь об истории вашего РЕПО.
альтернативой было:
- cd в базовую ветвь проекта
- удалить чувствительный код / файл
- rm-rf .ГИТ/ # удалить все мерзавец информация от ваш код
- перейдите в github и удалите свой репозиторий
- следуйте этому руководству, чтобы переместить свой код в новый репозиторий, как обычно - https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
Это, конечно, удалит все ветви истории фиксации и проблемы как из вашего РЕПО github, так и из вашего локального РЕПО git. Если это неприемлемо, вам придется использовать альтернативный вариант подход.
назовем это ядерным вариантом.
вот мое решение в windows
git filter-branch --tree-filter" rm-f 'filedir/filename' " HEAD
git push -- force
убедитесь, что путь правильный иначе это не сработает
надеюсь, это поможет
использовать filter-branch:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all git push origin *branch_name* -f
можно использовать
git forget-blob
.использование довольно просто
git forget-blob file-to-forget
. Вы можете получить дополнительную информацию здесьон исчезнет из всех коммитов в вашей истории, reflog, теги и так далее
я сталкиваюсь с одной и той же проблемой время от времени, и каждый раз, когда мне приходится возвращаться к этому сообщению и другим, именно поэтому я автоматизировал процесс.
кредиты для участников из Stack Overflow, которые позволили мне собрать это вместе
мне пришлось сделать это несколько раз на сегодняшний день. Обратите внимание, что это работает только на 1 файл за раз.
получить список всех коммитов, которые изменили файл. Тот, кто внизу будет первым совершать:
git log --pretty=oneline --branches -- pathToFile
чтобы удалить файл из истории используйте первый commit sha1 и путь к файлу из предыдущей команды, и заполните их в эту команду:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..