Как удалить неиспользуемые объекты из репозитория git?

Я случайно добавил, зафиксировал и нажал огромный двоичный файл с моей самой последней фиксацией в репозиторий Git.

Как я могу сделать Git удалить объекты, которые были/были созданы для этой фиксации, поэтому мой каталог .git снова сжимается до нормального размера?

Изменить: Спасибо за ваши ответы; Я попробовал несколько решений. Никто не работал. Например, один из GitHub удалил файлы из истории, но размер каталога .git не уменьшился:

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(

Ответ 1

Я ответил на это в другом месте и копирую здесь, так как я им горжусь!

... и без лишнего шума, могу ли я представить вам этот полезный script, git -gc-all, гарантированный для удаления всего вашего мусора git, пока они не появятся с дополнительными конфигурационными переменными:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "[email protected]"

Возможно, будет полезен параметр -агрессивный.

ПРИМЕЧАНИЕ: это приведет к удалению ВСЕХ необоснованных предметов, поэтому не плачьте мне, если позже вы решите, что хотите сохранить некоторые из них!

Возможно, вам также понадобится запустить что-то вроде этого сначала, о, дорогая, git сложно!

git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n1 --no-run-if-empty git update-ref -d

Я положил все это в script, здесь:

http://sam.nipl.net/b/git-gc-all-ferocious

Ответ 2

Ваш git reflog expire --all неверен. Он удаляет записи журнала, которые старше, чем время истечения срока действия, которое по умолчанию составляет 90 дней. Используйте git reflog expire --all --expire=now.

Мой ответ на аналогичный вопрос касается проблемы действительно очистки неиспользуемых объектов из репозитория.

Ответ 3

1) Удалите файл из git repo (& not fileystem):

  • git rm --cached path/to/file

2) Сжатие репо с помощью:

  • git gc,

  • или git gc --aggressive

  • или git prune

или комбинацию из вышеперечисленного, предложенную в этом вопросе: Уменьшить размер хранилища git

Ответ 4

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

Если вы хотите сохранить двоичный файл в репо для других людей, тогда нет реального способа сделать то, что вы хотите. Это почти все или ничего.

Ответ 5

Ключ для меня оказался под управлением git repack -A -d -f, а затем git gc, чтобы уменьшить размер одного пакета git, который у меня был.

Ответ 6

Hy!

Git получает только те объекты, которые ему нужны при клонировании репозиториев (если я правильно понимаю)

Таким образом, вы можете внести поправки в последнюю фиксацию, удалив файл, добавленный по ошибке, затем нажмите ваши изменения в удаленный репозиторий (с опцией -f для перезаписывания старого фиксации на сервере)

Затем, когда вы создаете новый клон этого репо, он должен быть таким же маленьким, как перед большим файлом.

Необязательно, если вы хотите удалить ненужные файлы с сервера, вы можете удалить репозиторий на сервере и нажать свою недавно клонированную копию (имеющую полную историю)

Ответ 7

git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all

Не забудьте изменить Filename для того, который вы хотите удалить из репозитория.