Как удалить неиспользуемые объекты из репозитория 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 :-(
8 ответов
Я ответил на это в другом месте, и буду копировать здесь, так как я горжусь этим!
... и без дальнейших церемоний, могу я представить вам этот полезный скрипт, 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
Я положил все это в сценарий, здесь:
Ваш git reflog expire --all
это неверно. Он удаляет записи reflog старше срока истечения, который по умолчанию равен 90 дням. использование git reflog expire --all --expire=now
,
Мой ответ на аналогичный вопрос посвящен проблеме реального удаления неиспользуемых объектов из хранилища.
1) Удалите файл из репозитория git (а не из файловой системы):
git rm --cached path/to/file
2) Сократите репо, используя:
git gc
,или же
git gc --aggressive
- или же
git prune
или сочетание вышеперечисленного, как предлагается в этом вопросе: Уменьшите размер хранилища git
Это руководство по удалению конфиденциальных данных можно применять, используя тот же метод. Вы будете переписывать историю, чтобы удалить этот файл из каждой ревизии, в которой он присутствовал. Это разрушительно и приведет к конфликтам репо с любыми другими проверками, поэтому сначала предупредите всех соавторов.
Если вы хотите, чтобы бинарный файл был доступен в репо для других людей, то нет реального способа сделать то, что вы хотите. Это почти все или ничего.
Ключ для меня оказался запущенным git repack -A -d -f
а потом git gc
чтобы уменьшить размер одного git пакета, который у меня был.
Hy!
Git получает только те объекты, которые ему действительно нужны, при клонировании репозиториев (если я правильно понимаю)
Таким образом, вы можете изменить последний коммит, удалив файл, добавленный по ошибке, а затем перенести изменения в удаленный репозиторий (с опцией -f также перезаписать старый коммит на сервере)
Затем, когда вы создаете новый клон этого репозитория, его каталог.git должен быть таким же маленьким, как и до фиксации больших файлов.
При желании, если вы также хотите удалить ненужные файлы с сервера, вы можете удалить репозиторий на сервере и отправить свою только что клонированную копию (с полной историей)
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all
Не забудьте изменить Filename
за тот, который вы хотите удалить из хранилища.
Смотрите раздел "Удаление объектов" в книге Pro Git:
http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery
Обновление: см. Также очиститель репозитория BFG: http://rtyley.github.io/bfg-repo-cleaner/
В 2020 году документация для git-filter-branch не одобряет его использование и рекомендует использовать альтернативу, такую как git-filter-repo. Его также можно использовать вместо BFG.
Обратите внимание, что глава о перезаписи истории в книге git не обновлялась. Также нет рекомендаций GitHub по удалению конфиденциальных данных.