Tôi không thể sử dụng câu trả lời phổ biến nhất vì --batch-check
chuyển đổi dòng lệnh sang Git 1.8.3 (mà tôi phải sử dụng) không chấp nhận bất kỳ đối số nào. Các bước tiếp theo đã được thử trên CentOS 6.5 với Bash 4.1.2
Ý chính
Trong Git, thuật ngữ blob ngụ ý nội dung của một tệp. Lưu ý rằng một cam kết có thể thay đổi nội dung của tệp hoặc tên đường dẫn. Do đó, cùng một tệp có thể đề cập đến một blob khác nhau tùy thuộc vào cam kết. Một tệp nhất định có thể là lớn nhất trong hệ thống phân cấp thư mục trong một cam kết, trong khi không phải trong một tệp khác. Do đó, câu hỏi về việc tìm kiếm các cam kết lớn thay vì các tệp lớn, đặt các vấn đề theo quan điểm chính xác.
Dành cho người thiếu kiên nhẫn
Lệnh in danh sách các đốm màu theo thứ tự kích thước giảm dần là:
git cat-file --batch-check < <(git rev-list --all --objects | \
awk '{print $1}') | grep blob | sort -n -r -k 3
Đầu ra mẫu:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e blob 305971200
7c357f2c2a7b33f939f9b7125b155adbd7890be2 blob 289163620
Để loại bỏ các đốm màu như vậy, hãy sử dụng BFG Repo Cleaner , như được đề cập trong các câu trả lời khác. Cho một tệp blobs.txt
chỉ chứa băm blob, ví dụ:
3a51a45e12d4aedcad53d3a0d4cf42079c62958e
7c357f2c2a7b33f939f9b7125b155adbd7890be2
Làm:
java -jar bfg.jar -bi blobs.txt <repo_dir>
Câu hỏi là về việc tìm kiếm các cam kết, công việc này nhiều hơn là tìm các đốm màu. Để biết, xin vui lòng đọc tiếp.
Công việc tiếp theo
Đưa ra một hàm băm cam kết, một lệnh in băm của tất cả các đối tượng được liên kết với nó, bao gồm các đốm màu, là:
git ls-tree -r --full-tree <commit_hash>
Vì vậy, nếu chúng ta có sẵn các đầu ra như vậy cho tất cả các xác nhận trong repo, sau đó đưa ra một hàm băm blob, thì các bó xác nhận là các kết quả khớp với bất kỳ đầu ra nào. Ý tưởng này được mã hóa trong đoạn script sau:
#!/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
Nếu nội dung được lưu trong một tệp có tên find-commits.sh
thì một lệnh gọi thông thường sẽ như dưới đây:
cat blobs.txt | find-commits.sh
Như trước đó, tập tin blobs.txt
liệt kê băm blob, mỗi dòng một dòng. Các create_db()
chức năng tiết kiệm bộ nhớ cache của tất cả các cam kết danh sách trong một thư mục con trong thư mục hiện hành.
Một số thống kê từ các thử nghiệm của tôi trên một hệ thống có hai bộ xử lý CPU Intel (R) Xeon (R) CPU E5-2620 2.00GHz được HĐH trình bày dưới dạng 24 lõi ảo:
- Tổng số lần xác nhận trong repo = gần 11.000
- Tốc độ tạo tệp = 126 tệp / s. Kịch bản tạo một tệp duy nhất cho mỗi lần xác nhận. Điều này chỉ xảy ra khi bộ đệm được tạo lần đầu tiên.
- Chi phí tạo bộ nhớ cache = 87 s.
- Tốc độ tìm kiếm trung bình = 522 lần xác nhận / s. Việc tối ưu hóa bộ đệm giúp giảm 80% thời gian chạy.
Lưu ý rằng tập lệnh là luồng đơn. Do đó, chỉ một lõi sẽ được sử dụng bất cứ lúc nào.