ฉันไม่สามารถใช้คำตอบที่ได้รับความนิยมมากที่สุดได้เนื่องจาก--batch-checkสวิตช์บรรทัดคำสั่งเป็น Git 1.8.3 (ที่ฉันต้องใช้) ไม่ยอมรับอาร์กิวเมนต์ใด ๆ มีการทดลองขั้นตอนต่อไปบน CentOS 6.5 ด้วย Bash 4.1.2
แนวคิดหลัก
ใน Git คำว่าblobหมายถึงเนื้อหาของไฟล์ โปรดทราบว่าการกระทำอาจเปลี่ยนแปลงเนื้อหาของไฟล์หรือชื่อพา ธ ดังนั้นไฟล์เดียวกันอาจหมายถึงหยดอื่นที่แตกต่างกันขึ้นอยู่กับการกระทำ ไฟล์บางไฟล์อาจใหญ่ที่สุดในลำดับชั้นของไดเรกทอรีในหนึ่งคอมมิชชันในขณะที่ไม่ได้อยู่ในอีกไฟล์หนึ่ง ดังนั้นคำถามของการค้นหาคำสัญญาที่มีขนาดใหญ่แทนที่จะเป็นไฟล์ขนาดใหญ่
สำหรับคนใจร้อน
คำสั่งเพื่อพิมพ์รายการของ blobs ตามลำดับจากมากไปน้อยคือ:
git cat-file --batch-check < <(git rev-list --all --objects | \
awk '{print $1}') | grep blob | sort -n -r -k 3
ตัวอย่างผลลัพธ์:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e blob 305971200
7c357f2c2a7b33f939f9b7125b155adbd7890be2 blob 289163620
หากต้องการลบ blobs ดังกล่าวให้ใช้BFG Repo Cleanerตามที่ระบุไว้ในคำตอบอื่น ๆ รับไฟล์blobs.txtที่มี hash blob เช่น:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e
7c357f2c2a7b33f939f9b7125b155adbd7890be2
ทำ:
java -jar bfg.jar -bi blobs.txt <repo_dir>
คำถามคือเกี่ยวกับการค้นหาความมุ่งมั่นซึ่งเป็นงานมากกว่าการค้นหา blobs หากต้องการทราบว่าโปรดอ่าน
การทำงานต่อไป
ให้แฮชการกระทำคำสั่งที่พิมพ์ hash ของวัตถุทั้งหมดที่เกี่ยวข้องกับมันรวมถึง blobs คือ:
git ls-tree -r --full-tree <commit_hash>
ดังนั้นถ้าเรามีเอาท์พุทดังกล่าวสำหรับคอมมิชชันทั้งหมดใน repo จากนั้นให้แฮชของหยดนั้นพวงของคอมมิทนั้นเป็นอันที่ตรงกับเอาท์พุทใด ๆ แนวคิดนี้ถูกเข้ารหัสในสคริปต์ต่อไปนี้:
#!/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
หากเนื้อหาถูกบันทึกในไฟล์ชื่อfind-commits.shการร้องขอทั่วไปจะอยู่ภายใต้:
cat blobs.txt | find-commits.sh
ก่อนหน้านี้ไฟล์blobs.txtจะแสดงรายการแฮชของหยดหนึ่งรายการต่อบรรทัด create_db()ฟังก์ชั่นบันทึกแคชของทั้งหมดที่กระทำรายชื่อในไดเรกทอรีย่อยในไดเรกทอรีปัจจุบัน
สถิติบางอย่างจากการทดลองของฉันในระบบที่มีโปรเซสเซอร์ Intel (R) Xeon (R) CPU E5-2620 2.00GHz สองตัวที่นำเสนอโดยระบบปฏิบัติการเป็น 24 คอร์เสมือน:
- จำนวนคอมมิตทั้งหมดใน repo = เกือบ 11,000
- ความเร็วในการสร้างไฟล์ = 126 ไฟล์ / s สคริปต์สร้างไฟล์เดียวต่อการส่งมอบ สิ่งนี้จะเกิดขึ้นเมื่อมีการสร้างแคชเป็นครั้งแรกเท่านั้น
- ค่าใช้จ่ายในการสร้างแคช = 87 วิ
- ความเร็วในการค้นหาเฉลี่ย = 522 คอมมิต / วิ การปรับให้เหมาะสมของแคชส่งผลให้เวลาในการรันลดลง 80%
โปรดทราบว่าสคริปต์เป็นเธรดเดียว ดังนั้นจะใช้แกนเดียวเท่านั้นในช่วงเวลาหนึ่ง