Nie mogłem skorzystać z najpopularniejszej odpowiedzi, ponieważ --batch-checkprzełącznik wiersza poleceń do Git 1.8.3 (z którego muszę korzystać) nie przyjmuje żadnych argumentów. Kolejne kroki zostały wypróbowane na CentOS 6.5 z Bash 4.1.2
Kluczowe idee
W Git termin „ kropelka” oznacza zawartość pliku. Zauważ, że zatwierdzenie może zmienić zawartość pliku lub nazwy ścieżki. Zatem ten sam plik może odnosić się do innego obiektu blob w zależności od zatwierdzenia. Pewny plik może być największy w hierarchii katalogów w jednym zatwierdzeniu, a nie w innym. Dlatego kwestia znalezienia dużych zatwierdzeń zamiast dużych plików stawia sprawy we właściwej perspektywie.
Dla niecierpliwych
Polecenie drukowania listy obiektów blob w malejącej kolejności wielkości to:
git cat-file --batch-check < <(git rev-list --all --objects | \
awk '{print $1}') | grep blob | sort -n -r -k 3
Przykładowe dane wyjściowe:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e blob 305971200
7c357f2c2a7b33f939f9b7125b155adbd7890be2 blob 289163620
Aby usunąć takie obiekty BLOB, użyj BFG Repo Cleaner , jak wspomniano w innych odpowiedziach. Biorąc pod uwagę plik, blobs.txtktóry zawiera tylko skróty obiektów blob, na przykład:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e
7c357f2c2a7b33f939f9b7125b155adbd7890be2
Zrobić:
java -jar bfg.jar -bi blobs.txt <repo_dir>
Pytanie dotyczy znalezienia zatwierdzeń, co jest więcej pracy niż znalezienie obiektów blob. Aby wiedzieć, czytaj dalej.
Dalsza praca
Biorąc pod uwagę skrót zatwierdzenia, polecenie, które drukuje skróty wszystkich powiązanych z nim obiektów, w tym obiektów blob, to:
git ls-tree -r --full-tree <commit_hash>
Tak więc, jeśli mamy takie wyjścia dostępne dla wszystkich zatwierdzeń w repozytorium, to biorąc pod uwagę skrót obiektu blob, wiązka zatwierdzeń to te, które pasują do któregokolwiek z wyników. Ta idea jest zakodowana w następującym skrypcie:
#!/bin/bash
DB_DIR='trees-db'
find_commit() {
cd ${DB_DIR}
for f in *; do
if grep -q $1 ${f}; then
echo ${f}
fi
done
cd - > /dev/null
}
create_db() {
local tfile='/tmp/commits.txt'
mkdir -p ${DB_DIR} && cd ${DB_DIR}
git rev-list --all > ${tfile}
while read commit_hash; do
if [[ ! -e ${commit_hash} ]]; then
git ls-tree -r --full-tree ${commit_hash} > ${commit_hash}
fi
done < ${tfile}
cd - > /dev/null
rm -f ${tfile}
}
create_db
while read id; do
find_commit ${id};
done
Jeśli zawartość zostanie zapisana w pliku o nazwie, find-commits.shtypowe wywołanie będzie wyglądać tak:
cat blobs.txt | find-commits.sh
Podobnie jak wcześniej, plik blobs.txtzawiera skróty obiektów blob, po jednym w wierszu. create_db()Funkcja oszczędza pamięć podręczna wszystkim popełnić ofert w podkatalogu w katalogu bieżącym.
Niektóre statystyki z moich eksperymentów na systemie z dwoma procesorami Intel (R) Xeon (E) E5-2620 2,00 GHz, przedstawionymi przez system operacyjny jako 24 rdzenie wirtualne:
- Całkowita liczba zatwierdzeń w repo = prawie 11 000
- Szybkość tworzenia pliku = 126 plików / s. Skrypt tworzy jeden plik na zatwierdzenie. Dzieje się tak tylko wtedy, gdy pamięć podręczna jest tworzona po raz pierwszy.
- Narzut związany z tworzeniem pamięci podręcznej = 87 s.
- Średnia prędkość wyszukiwania = 522 zatwierdzeń / s. Optymalizacja pamięci podręcznej spowodowała 80% skrócenie czasu działania.
Zauważ, że skrypt jest jednowątkowy. Dlatego tylko jeden rdzeń byłby używany w tym samym czasie.