Как удалить неиспользуемые объекты из репозитория git? - PullRequest
74 голосов
/ 26 сентября 2010

Я случайно добавил, зафиксировал и отправил огромный двоичный файл с моим самым последним коммитом в 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 :-(

Ответы [ 8 ]

114 голосов
/ 06 февраля 2013

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

... и без лишних слов, могу я представить вам этот полезный скрипт, 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 "$@"

Может быть полезен параметр --aggressive.

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

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

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

Я положил все это в сценарий, здесь:

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

25 голосов
/ 29 сентября 2010

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

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

17 голосов
/ 18 марта 2013

1) Удалите файл из git-репо (а не из файловой системы):

  • git rm --cached path/to/file

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

  • git gc,

  • или git gc --aggressive

  • или git prune

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

10 голосов
/ 26 сентября 2010

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

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

7 голосов
/ 30 апреля 2013

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

6 голосов
/ 21 июля 2011

Hy!

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

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

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

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

4 голосов
/ 03 июня 2013

См. «Удаление объектов» в книге Pro Git:

http://git -scm.com / book / ru / Git-Internals-Maintenance-and-Data-Recovery # Removing-Objects

Обновление: см. Также BFG очиститель репо: http://rtyley.github.io/bfg-repo-cleaner/

4 голосов
/ 17 мая 2012
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...