#!/usr/bin/env bash
# git lspacks -- list packfiles in the current Git repository

if [[ $1 == --total ]]; then
	git cat-file --batch-all-objects --batch-check='%(objectname) %(objectsize)' | awk 'BEGIN { print "[...]" } { total += $2; print "\033[A\033[J[" substr($1, 0, 12) "...] " NR " objects, " total/1024/1024 " MB total" }'
	exit
fi

git=$(git rev-parse --git-dir)
obj=$git/objects
dir=$obj/pack

# show packfile list

declare -A packs=()
declare -A kept=()
declare -A temp=()

for file in "$dir"/* "$dir"/.tmp-*; do
	base=${file%.*}
	base=${base##*/}
	case $file in
	*.pack)
		packs[$base]=$(du -hs "$file" | awk '{print $1}');;
	*.keep)
		kept[$base]=1;;
	esac
done

for pack in "${!packs[@]}"; do
	size=${packs[$pack]}
	if [[ ${kept[$pack]} ]]; then
		keep='K'
	else
		keep='-'
	fi
	printf '%6s %1s %s\n' "$size" "$keep" "$pack"
done | sort -h

# count loose objects, show summary

size_packs=$(du -hs "$dir" | awk '{print $1}')
size_index=$(du -hsc "$dir"/*.idx 2>/dev/null | awk '$2 == "total" {print $1}')
size_loose=$(du -hsc "$obj"/??/ 2>/dev/null | awk '$2 == "total" {print $1}')
size_total=$(du -hs "$obj" | awk '{print $1}')
n_loose=$(find "$obj"/??/ -type f 2>/dev/null | wc -l)

printf '\n'
printf '%6s   %s\n' \
	"$size_packs" "all packs" \
	"$size_index" "└ pack indexes" \
	"$size_loose" "$n_loose loose objects" \
	"$size_total" "total" ;
