Подтвердить что ты не робот

Удалите большой файл .pack, созданный git

Я проверил загрузку файлов в ветку и объединился, а затем должен был удалить их, и теперь у меня остался большой файл .pack, который я не знаю, как избавиться.

Я удалил все файлы с помощью git rm -rf xxxxxx, и я также использовал параметр --cached.

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

.git/objects/pack/pack-xxxxxxxxxxxxxxxxx.pack

Нужно ли мне просто удалить ветку, которая у меня есть, но больше не использую? Или есть что-то еще, что мне нужно запустить?

Я не уверен, какая разница, но он показывает блокировку файла.

Спасибо


ИЗМЕНИТЬ

Вот некоторые отрывки из моей bash_history, которые должны дать представление о том, как мне удалось попасть в это состояние (предположим, что в данный момент я работаю над ветвью git, называемой "my-branch", и у меня есть папка, содержащая больше папок/файлов):

git add .
git commit -m "Adding my branch changes to master"
git checkout master
git merge my-branch
git rm -rf unwanted_folder/
rm -rf unwanted_folder/     (not sure why I ran this as well but I did)

Я думал, что я также запускал следующее, но он не появляется в bash_history с остальными:

git rm -rf --cached unwanted_folder/

Мне также показалось, что я запускал несколько команд git (например, git gc), чтобы попытаться упорядочить файл пакета, но они также не отображаются в файле .bash_history.

4b9b3361

Ответ 1

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

То, что вы хотите сделать, называется переписыванием истории, и в нем задействована команда git filter-branch.

У GitHub есть хорошее объяснение проблемы на их сайте. https://help.github.com/articles/remove-sensitive-data

Чтобы ответить на ваш вопрос более прямо, вам нужно выполнить следующую команду с соответствующей заменой unwanted_filename_or_folder:

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch unwanted_filename_or_folder' --prune-empty

Это удалит все ссылки на файлы из активной истории репо.

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

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --prune=now

Ответ 2

Сценарий A. Если ваши большие файлы были добавлены только в ветку, вам не нужно запускать git filter-branch. Вам просто нужно удалить ветку и запустить сборку мусора:

git branch -D mybranch
git reflog expire --expire-unreachable=all --all
git gc --prune=all

Сценарий B. Однако похоже, что на основе истории bash вы объединили изменения в мастер. Если вы не поделились изменениями с кем-либо (еще нет git push). Проще всего было бы reset вернуть мастер до слияния с веткой, в которой были большие файлы. Это устранит все фиксации из вашего ветки и все фиксации, сделанные для освоения после слияния. Таким образом, вы можете потерять изменения - в дополнение к большим файлам - которые вы, возможно, действительно хотели:

git checkout master
git log # Find the commit hash just before the merge
git reset --hard <commit hash>

Затем выполните шаги из сценария A.

Сценарий C. Если бы изменения в ветке или изменились на мастер после слияния, которые вы хотите сохранить, было бы лучше переустановить мастер и выборочно включить фиксации, которые вы хотите:

git checkout master
git log # Find the commit hash just before the merge
git rebase -i <commit hash>

В редакторе удалите строки, соответствующие коммитам, которые добавили большие файлы, но оставьте все остальное как есть. Сохранить и выйти. В вашей основной ветке должно быть только то, что вы хотите, и больших файлов. Обратите внимание, что git rebase без -p устраняет комманды слияния, поэтому после <commit hash> вы оставите линейную историю для мастера. Это, вероятно, хорошо для вас, но если нет, вы можете попробовать с -p, но git help rebase говорит combining -p with the -i option explicitly is generally not a good idea unless you know what you are doing.

Затем запустите команды из сценария A.

Ответ 3

Один вариант:

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

Другой вариант - сохранить код и .git где-нибудь, а затем удалить .git и начать снова с использованием этого существующего кода, создав новый репозиторий git (git init).

Ответ 4

Как уже указывал в своем ответе loganfsmyth, вам нужно очистить историю git, потому что файлы продолжают существовать там даже после удаления их из репо. Официальные документы GitHub рекомендуют BFG, которые я считаю более удобными, чем filter-branch:

Удаление файлов из истории

Загрузите BFG со своего сайта. Убедитесь, что у вас установлена Java, затем создайте зеркальный клон и историю очистки. Обязательно замените YOUR_FILE_NAME именем файла, который вы хотите удалить:

git clone --mirror git://example.com/some-big-repo.git
java -jar bfg.jar --delete-files YOUR_FILE_NAME some-big-repo.git
cd some-big-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push

Удаление папки

То же, что и выше, но используйте --delete-folders

java -jar bfg.jar --delete-folders YOUR_FOLDER_NAME some-big-repo.git

Другие опции

BFG также позволяет использовать даже более удобные опции (см. Docs) следующим образом:

Удалите все файлы размером более 100M из истории:

java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git

Важный!

При запуске BFG будьте осторожны, что как YOUR_FILE_NAME и YOUR_FOLDER_NAME действительно являются именами файлов и папок. Это не дорожки, поэтому что-то вроде foo/bar.jpg не будет работать! Вместо этого все файлы/папки с указанным именем будут удалены из истории репо, независимо от того, какой путь или ветвь они существуют.

Ответ 5

Я немного опоздал на шоу, но в случае, если вышеупомянутый ответ не решил запрос, я нашел другой способ. Просто удалите конкретный большой файл из.pack. У меня была эта проблема, когда я случайно зарегистрировался в большом файле размером 2 ГБ. Я выполнил шаги, описанные в этой ссылке: http://www.ducea.com/2012/02/07/howto-completely-remove-a-file-from-git-history/

Ответ 6

Запустите следующую команду, заменив PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA на путь к файлу, который вы хотите удалить, а не только на имя файла. Эти аргументы будут:

  1. Заставить Git обрабатывать, но не проверять всю историю каждой ветки и тега
  2. Удалить указанный файл, а также любые пустые коммиты, сгенерированные в результате
  3. Перезаписать существующие теги
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" --prune-empty --tag-name-filter cat -- --all

Это принудительно удалит все ссылки на файлы из активной истории репо.

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

git update-ref -d refs/original/refs/remotes/origin/master
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --aggressive --prune=now

Ответ 7

это более удобное решение, чем кодирующее. почтовый файл. Откройте zip в формате просмотра файлов (отличается от распаковки). Удалить .pack файл. Разархивируйте и замените папку. Работает как шарм!