Как узнать, какие файлы занимают больше всего места в репозитории git?
Мне нужно сделать репо меньше. Я думаю, что я могу уменьшить его, удалив проблемные двоичные файлы из истории git:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch BigFile'
И затем освобождение объектов:
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --aggressive --prune=now
(Не стесняйтесь комментировать, если эти команды ошибочны.)
Проблема: как определить эти большие файлы, чтобы я мог осмелиться удалить их из истории git? Скорее всего, они больше не находятся в рабочем дереве - они были удалены и, вероятно, также не отслеживаются:
git rm --cached BigFile
Ответы
Ответ 1
twalberg answer делает трюк. Я завернул его в цикл, чтобы вы могли перечислять файлы по порядку по размеру:
while read -r largefile; do
echo $largefile | awk '{printf "%s %s ", $1, $3 ; system("git rev-list --all --objects | grep " $1 " | cut -d \" \" -f 2-")}'
done <<< "$(git rev-list --all --objects | awk '{print $1}' | git cat-file --batch-check | sort -k3nr | head -n 20)"
head -n 20
ограничивает вывод в верхней части 20. При необходимости измените.
После того, как вы определили файлы проблем, ознакомьтесь с этим, чтобы узнать, как их удалить.
Ответ 2
Вы можете найти хеш-идентификаторы самых больших объектов, таких как:
git rev-list --all --objects | awk '{print $1}' | git cat-file --batch-check | sort -k3nr
Затем для определенного SHA вы можете сделать это, чтобы получить имя файла:
git rev-list --all --objects | grep <SHA>
Не уверен, есть ли более эффективный способ сделать это. Если вы точно знаете, что все в файлах pack (не потерянных объектов), git verify-pack -v
производит вывод, который включает в себя размер, и я, кажется, помню, что видел script где-нибудь, который будет анализировать этот вывод и сопоставлять каждый объект с исходные файлы.
Ответ 3
Я написал script, который расскажет вам о самых больших объектах, файлах или каталогах в моем ответе здесь. Без аргументов он укажет размер всех объектов, отсортированных по размеру. Вы можете сказать ему --sum
или --directories
, чтобы суммировать все объекты для каждого файла и распечатать их, или сделать то же самое для всех файлов в каждом каталоге. Надеюсь, это полезно!
Ответ 4
Не могу не оптимизировать ответ MatrixManAtYrService:
git rev-list --all --objects | git cat-file --batch-check='%(objectname) %(objecttype) %(objectsize) %(rest)' | grep blob | sort -k3nr | head -n 20
Таким образом, git rev-list
вызывается только один раз (а не для каждого отображаемого объекта), и сценарий более понятен.