--batch-check
Git 1.8.3으로 의 명령 행 스위치 (사용해야 함)가 인수를 허용하지 않기 때문에 가장 인기있는 답변 을 사용할 수 없었습니다. 다음 단계는 Bash 4.1.2가 설치된 CentOS 6.5에서 시도되었습니다.
주요 컨셉
Git에서 Blob 이라는 용어 는 파일의 내용을 의미합니다. 커밋은 파일 또는 경로 이름의 내용을 변경할 수 있습니다. 따라서 커밋에 따라 동일한 파일이 다른 얼룩을 참조 할 수 있습니다. 특정 파일은 한 커밋에서 다른 계층이 아닌 디렉토리 계층 구조에서 가장 클 수 있습니다. 따라서 큰 파일 대신 큰 커밋을 찾는 문제는 올바른 관점에 있습니다.
참을성없는 사람들을 위해
내림차순으로 BLOB 목록을 인쇄하는 명령은 다음과 같습니다.
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
이러한 얼룩을 제거하려면 다른 답변에서 언급 한대로 BFG Repo Cleaner를 사용하십시오 . blobs.txt
Blob 해시 만 포함 된 파일 을 예로 들면 다음과 같습니다.
3a51a45e12d4aedcad53d3a0d4cf42079c62958e
7c357f2c2a7b33f939f9b7125b155adbd7890be2
하다:
java -jar bfg.jar -bi blobs.txt <repo_dir>
문제는 커밋을 찾는 것입니다. 이는 커밋을 찾는 것보다 더 많은 작업입니다. 알고 싶다면 계속 읽으십시오.
추가 작업
커밋 해시가 주어지면 Blob을 포함하여 연결된 모든 객체의 해시를 인쇄하는 명령은 다음과 같습니다.
git ls-tree -r --full-tree <commit_hash>
따라서 리포지토리의 모든 커밋에 대해 이러한 출력을 사용할 수 있다면 Blob 해시가 주어지면 커밋이 출력과 일치하는 커밋입니다. 이 아이디어는 다음 스크립트로 인코딩됩니다.
#!/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
에는 한 줄에 하나씩 Blob 해시가 나열됩니다. 이 create_db()
함수는 모든 커밋 목록의 캐시를 현재 디렉토리의 하위 디렉토리에 저장합니다.
OS에서 24 개의 가상 코어로 제공되는 두 개의 Intel Xeon CPU E5-2620 2.00GHz 프로세서가있는 시스템에서 실험 한 일부 통계 :
- 리포지토리의 총 커밋 수 = 거의 11,000
- 파일 생성 속도 = 126 파일 / 초 스크립트는 커밋 당 하나의 파일을 만듭니다. 캐시가 처음 생성 될 때만 발생합니다.
- 캐시 생성 오버 헤드 = 87 초
- 평균 검색 속도 = 522 commits / s. 캐시 최적화로 실행 시간이 80 % 단축되었습니다.
스크립트는 단일 스레드입니다. 따라서 한 번에 하나의 코어 만 사용됩니다.