git: не могу найти blob - хочу избавиться от него из пакета

У меня большая клякса, от которой я хочу избавиться! Я думал, что удалил файл с помощью этого решения: http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/ (я использовал -- --all вместо HEAD, чтобы файлы удалялись из всех веток )

rm -rf .git/refs/original/ && git reflog expire --all &&  
    git gc --aggressive --prune

Я просмотрел папку пакета через этот Почему мой git репозиторий такой большой?

$ git verify-pack -v .git/objects/pack/pack-*.idx | sort -k3n
... last 4 lines:
bc7ae9801052180b283cd81880753549f0f92587 blob   19464809 749446 305054873
acd5f09a35846bec25ebc324738139e5caabc50f blob   294278199 71381636 39607483
986d152935434b56cf182d8a32e24cb57af75ac3 blob   480385718 108184804 110989119
ba9d1d27ee64154146b37dfaf42ededecea847e1 blob   761172819 27430741 277589990

Скрипт git-find-blob взят из В каком коммите есть этот большой двоичный объект?

$ ./git-find-blob ba9d1d27ee64154146b37dfaf42ededecea847e1

Но ничего не находит.

Есть идеи, как избавиться от него из моего репозитория?


person EoghanM    schedule 15.09.2011    source источник
comment
Выход git status пуст? Возможно, большой двоичный объект был добавлен в индекс, но не зафиксирован.   -  person Mark Longair    schedule 16.09.2011
comment
Было бы полезно, если бы вы также включили вывод git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") и ту же команду без --cache   -  person Mark Longair    schedule 16.09.2011
comment
Спасибо за ваше постоянное внимание, Марк; большой двоичный объект указан в обоих вариантах команды как «недоступный большой двоичный объект». В варианте без флага --cache указано 7 (других) дополнительных недостижимых BLOB-объектов.   -  person EoghanM    schedule 19.09.2011
comment
Реф упакован? Он появляется в git show-ref?   -  person Josh Lee    schedule 21.09.2011
comment
@MarkLongair спасибо! Я пробовал все, чтобы удалить из репо 2 ГБ лишних блобов, не понимая, что они все время были в индексе! (подготовлено к удалению)   -  person thenickdude    schedule 09.07.2015


Ответы (5)


Вы можете использовать git repack -Ad, чтобы заставить git реконструировать ваши пакеты и распаковать любые недостижимые объекты на отдельные объекты. На этом этапе вы можете использовать git gc --prune=now, чтобы отбросить недостижимые объекты.

Вы также должны дважды проверить, действительно ли срок действия ваших журналов истек. Я считаю, что git reflog expire --all по умолчанию будет 90 дней (или 30 для недоступных объектов), поэтому вы можете вместо этого использовать git reflog expire --expire-unreachable=now --all (это нужно сделать до репака + gc).

person Lily Ballard    schedule 21.09.2011
comment
спасибо, это сработало! reflog истекает с unreachable = now И gc --prune = now после переупаковки сделал свое дело. первый очистил эту последнюю ссылку, а второй избавился от самого объекта. - person Harald Schilly; 06.01.2012
comment
Здорово! У меня тоже сработало. Репо увеличилось с 80 МБ до 4,5 МБ. - person Leo; 09.02.2012

Во-первых, в вызове git gc вы должны использовать --prune=now, поскольку по умолчанию сохраняются объекты, которым меньше двух недель.

Во-вторых, команда git-find-blob, которую вы использовали по умолчанию, просматривает только историю HEAD на предмет коммитов, поэтому, если большой двоичный объект находится в другой ветке, этот скрипт его пропустит. Попробуйте вызвать его как:

./git-find-blob ba9d1d27ee64154146b37dfaf42ededecea847e1 --all
person Mark Longair    schedule 15.09.2011
comment
Я пробовал --all как на perl, так и на bash версии git-find-blob, но все равно не играла в кости. Я также пробовал --prune=now на gc --aggressive, но капля все еще там! - person EoghanM; 15.09.2011

Вы хотите использовать BFG Repo-Cleaner, более быструю и простую альтернативу git-filter-branch разработанному для удаления больших файлов из репозиториев Git.

Загрузите Java jar (требуется Java 6 или более поздней версии) и выполните следующую команду:

$ java -jar bfg.jar  --strip-blobs-bigger-than 20M  my-repo.git

Любой большой двоичный объект размером более 20 МБ (которого нет в вашей последней фиксации) будет полностью удален из истории вашего репозитория. Затем вы можете использовать git gc для очистки мертвых данных:

$ git gc --prune=now --aggressive

BFG обычно в 10-50 раз быстрее, чем работает git-filter-branch, и параметры адаптированы для этих двух распространенных сценариев использования:

  • Удаление безумно больших файлов
  • Удаление паролей, учетных данных и других личных данных

Полное раскрытие информации: я являюсь автором BFG Repo-Cleaner.

person Roberto Tyley    schedule 01.02.2013

Капля не появляется с другой стороны от чистого проталкивания, так что это будет моим решением (протолкнуть в новое место, а затем клонировать из этого места). Есть ли более простой способ сделать это?

person EoghanM    schedule 21.09.2011

Имея ту же проблему. Обнаружил, что на мою неприятную каплю ссылается недостижимое дерево. Добавление в скрипт git-find-blob:

git fsck --full --unreachable | \
while read unreachable obj tree
do
    if [[ ! $obj == "tree" ]]; then
        continue
    fi
    if git ls-tree -r $tree | grep -q "$obj_name" ; then
        echo "$unreachable $obj $tree"
    fi
done

Мне удалось удалить blob-объект с помощью BFG Repo-Cleaner, но я был бы намного счастливее решить проблему с помощью собственных команд git.

person Doug    schedule 08.10.2013