Удалить большой.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.

8 ответов

Решение

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

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

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

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

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch unwanted_folename_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

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

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

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

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

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

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

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,

Затем выполните команды из сценария А.

Выполните следующую команду, заменив 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

Как 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 также позволяет использовать даже более изящные варианты (см. Документы):

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

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

Важный!

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

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

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

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

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

Это использует BFG в соответствии с рекомендациями GitHub, так же, как ответ @Timo, но с небольшим изменением, так как я потратил некоторое время на просмотр параметров CLI.

Допустим, я отправил изображения с более чем60MBнекоторое время назад, и я не могу отменить фиксацию. Я бы просто запустил следующее

      java -jar /jarfiles/bfg-1.14.0.jar --delete-files '*.{png,jpg,JPG,PNG}'

Затем я получу предложение запустить следующую команду, которую я сделаю

       git reflog expire --expire=now --all && git gc --prune=now --aggressive

Наконец, синхронизируйте изменения на пульте с

      git push --force

Вы можете убедиться, что размер файла пакета уменьшился с помощью

      du -sh ./

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

Другие вопросы по тегам