Как я могу очистить папку .git? Очистил каталог моего проекта, но .git по-прежнему огромен

86

В .git / объекты в моих рельсах проецировать каталог еще массивный, после удаления сотни мегабайта случайно сгенерированного мусора.

Я пробовал git add -A, как и другие команды, обновить индекс и удалить несуществующие файлы. Я полагаю, возможно, неправильно, что файлы с двухсимвольными именами в каталоге являются каплями. Я попытался вернуться к предыдущим коммитам, но безуспешно.

Что я могу сделать, чтобы очистить этот каталог?

лампочки
источник

Ответы:

139
  • Если вы добавили файлы, а затем удалили их, капли все еще существуют, но болтаются. git fsckотобразит список недоступных BLOB-объектов и git pruneудалит их.

  • Если вы добавили файлы, зафиксировали их, а затем откатили git reset --hard HEAD^, они застрянут еще глубже. git fsckне будет перечислять какие-либо висячие коммиты или капли, потому что журнал ссылок вашей ветки удерживает их. Вот один из способов гарантировать, что останутся только те объекты, которые находятся в вашей истории:

    git reflog expire --expire=now --all
    git repack -ad  # Remove dangling objects from packfiles
    git prune       # Remove dangling loose objects
    
  • Другой способ - также клонировать репозиторий, так как он будет содержать только те объекты, которые доступны. Однако, если висячие объекты были упакованы (и если вы выполнили много операций, git вполне мог упаковаться автоматически), то локальный клон будет нести весь pack-файл:

    git clone foo bar                 # bad
    git clone --no-hardlinks foo bar  # also bad
    

    Вы должны указать протокол, чтобы заставить git вычислить новый пакет:

    git clone file://foo bar  # good
    
Джош Ли
источник
Да, я совершил совершение, прежде чем заметил проблему. Я пробовал все, кроме последней команды. Когда я запускаю это из каталога моего проекта, «предупреждение: похоже, вы клонировали пустой репозиторий». Читал документацию, но это тяжелая штука. Как я могу указать клонирование на правильный источник?
light24bulbs
1
@user file://fooURL-адрес относительно текущего каталога, а file:///home/me/foo(три косой черты) является абсолютным.
Джош Ли
благодаря! это вдвое меньше, но мой пакет по-прежнему в десять раз больше, чем остальная часть репозитория. Я пробовала
обрезать
1
@user Если у многих коммитов есть большие файлы по ошибке, вы можете использовать git-filter-branch, чтобы выбрать их.
Джош Ли
2
К сожалению, безрезультатно. Мой руководитель говорит, что размер теперь находится в приемлемом, но неблагоприятном диапазоне. Если у вас есть время, чтобы кормить меня с ложечки, это было бы прекрасно, но вы снова поставили меня на ноги. Спасибо jleedev.
light24bulbs
34

Вы пробовали git gcкоманду?

Райанпрайого
источник
3
git gc --aggressive --pruneработает на меня. git gcне. Может быть, настройки по умолчанию недостаточно.
Moonlight Knight
15

Sparkleshare создал 13 ГБ файлов tmp_pack_ в моем git после того, как много раз не смог выполнить проверку огромных изображений. Единственное, что помогло, это ...

rm -f .git/objects/*/tmp_*

«git gc» не удалял эти файлы.

Кот
источник
Это довольно грубое решение, но я не вижу причин, по которым оно не сработает. Ницца!
light24bulbs
1
Безвыходные ситуации требуют отчаянных мер, Это сработало как шарм! Ткс.
Медина
rm для команды linux? как насчет пользователя Windows тогда @cat?
gumuruh
7

Если у вас все еще есть большое репо после обрезки и переупаковки ( gc --aggressive --prune=tomorrow...), вы можете просто поискать лишнее:

git rev-list --objects --all |
    while read sha1 fname
    do 
        echo -e "$(git cat-file -s $sha1)\t$\t$fname"
    done | sort -n

Это даст вам отсортированный список объектов по возрастанию. Вы можете использовать git-filter-branch, чтобы удалить виновника из вашего репо.

См. «Удаление объектов» в http://progit.org/book/ch9-7.html для руководства.

sehe
источник
@DavidJames, спасибо за подсказку. Я сделал его еще более читаемым, ИМО
см.
На всякий случай, если кто-то еще споткнется об этом: в аргументах в скобках есть опечатка: должно быть --aggressive. Пытался отредактировать, но оказалось, что такую ​​мелкую опечатку отредактировать нельзя.
hellobenallan
@hellobenallan, спасибо за заметку, исправлено
см
1

Рекурсивно:

find ./ -iname '*.!*' -size 0 -delete
for i in */.git; do ( echo $i; cd $i/..; git gc --aggressive --prune=now --force; ); done
Марсело Гребуа
источник