Saya tidak dapat menggunakan jawaban yang paling populer karena --batch-check pergantian baris perintah ke Git 1.8.3 (yang harus saya gunakan) tidak menerima argumen apa pun. Langkah selanjutnya telah dicoba pada CentOS 6.5 dengan Bash 4.1.2
Konsep Kunci
Dalam Git, istilah gumpalan menyiratkan isi file. Perhatikan bahwa komit dapat mengubah konten file atau pathname. Dengan demikian, file yang sama dapat merujuk ke gumpalan yang berbeda tergantung pada komit. File tertentu bisa menjadi yang terbesar dalam hierarki direktori dalam satu komit, sementara tidak di yang lain. Oleh karena itu, pertanyaan menemukan commit besar dan bukan file besar, menempatkan hal-hal dalam perspektif yang benar.
Untuk Yang Tidak Sabar
Perintah untuk mencetak daftar gumpalan dalam urutan ukuran menurun adalah:
git cat-file --batch-check < <(git rev-list --all --objects | \
awk '{print $1}') | grep blob | sort -n -r -k 3
Output sampel:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e blob 305971200
7c357f2c2a7b33f939f9b7125b155adbd7890be2 blob 289163620
Untuk menghilangkan gumpalan seperti itu, gunakan BFG Repo Cleaner , seperti disebutkan dalam jawaban lain. Diberikan file blobs.txtyang hanya berisi hash gumpalan, misalnya:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e
7c357f2c2a7b33f939f9b7125b155adbd7890be2
Melakukan:
java -jar bfg.jar -bi blobs.txt <repo_dir>
Pertanyaannya adalah tentang menemukan komitmen, yang lebih berfungsi daripada menemukan gumpalan. Untuk tahu, silakan baca terus.
Pekerjaan selanjutnya
Diberi hash komit, perintah yang mencetak hash dari semua objek yang terkait dengannya, termasuk gumpalan, adalah:
git ls-tree -r --full-tree <commit_hash>
Jadi, jika kita memiliki output seperti itu tersedia untuk semua komit di repo, maka diberi hash gumpalan, banyak komit adalah yang cocok dengan salah satu output. Ide ini dikodekan dalam skrip berikut:
#!/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
Jika konten disimpan dalam nama file find-commits.shmaka doa biasa akan seperti di bawah:
cat blobs.txt | find-commits.sh
Seperti sebelumnya, file blobs.txtmencantumkan hash gumpalan, satu per baris. Itucreate_db() fungsi menyimpan cache dari semua berkomitmen listing di sub-direktori dalam direktori saat ini.
Beberapa statistik dari percobaan saya pada sistem dengan dua prosesor Intel (R) Xeon (R) CPU E5-2620 2.00GHz yang disajikan oleh OS sebagai 24 inti virtual:
- Total jumlah komitmen dalam repo = hampir 11.000
- Kecepatan pembuatan file = 126 file / s. Script membuat satu file per komit. Ini terjadi hanya ketika cache sedang dibuat untuk pertama kalinya.
- Overhead pembuatan cache = 87 dtk.
- Kecepatan pencarian rata-rata = 522 komit / s. Optimasi cache menghasilkan pengurangan 80% dalam waktu berjalan.
Perhatikan bahwa skrip ini adalah utas tunggal. Karena itu, hanya satu inti yang akan digunakan pada satu waktu.