TrotVote
[IT 심층 분석]

수백 GB로 팽창한 Git 저장소 다이어트 작업: LFS 마이그레이션과 BFG를 이용한 히스토리 정리 완전판

김민준 · IT 시스템 엔지니어|
어느 날 신규 팀원이 프로젝트를 클론하는 데 한 시간이 넘게 걸린다고 토로했습니다. clone하는 저장소의 크기를 확인해보니 무려 47GB에 달했습니다. 순수 소스 코드만 담긴 저장소가 이 크기가 될 이유는 없습니다. git log를 샅샅이 뒤지자 수년 전 개발 초기 시절에 누군가가 머신러닝 학습을 위한 수백 메가바이트짜리 학습 데이터셋 바이너리 파일들과 라이브러리 DLL 파일들을 Git에 직접 커밋해버린 과거가 그대로 역사에 남아있었습니다. 나중에 해당 파일들을 git rm으로 제거했지만 Git의 특성상 과거 커밋 히스토리에는 여전히 그 파일들이 객체로 남아있어 저장소 크기를 차지하고 있었습니다. 이 문제를 해결하는 과정은 두 단계로 나뉘었습니다. 첫 번째는 과거 히스토리에서 대용량 파일을 영구 삭제하는 것, 두 번째는 앞으로 사업 과정에서 같은 실수가 반복되지 않도록 LFS 구조를 도입하는 것이었습니다. 과거 히스토리 정리를 위해선 git filter-branch 보다 훨씬 빠르고 안전한 Java 도구인 BFG Repo-Cleaner를 사용했습니다. bfg --strip-blobs-bigger-than 100M 명령 하나로 100MB 이상의 모든 바이너리 블롭을 히스토리 전체에서 외과적으로 제거했습니다. 이후 git reflog expire와 git gc를 통해 참조가 사라진 고아 객체들을 물리적으로 정리하고 나니 저장소 크기가 47GB에서 580MB로 99% 가까이 줄어들었습니다. 앞으로의 재발 방지를 위해 Git LFS(Large File Storage)를 적용했습니다. LFS는 대용량 파일을 실제 Git 오브젝트 데이터베이스에 저장하는 대신 해당 파일의 포인터만을 커밋에 저장하고 실제 파일 내용은 별도의 LFS 스토리지에 보관하는 방식입니다. 클론 시에는 기본적으로 현재 브랜치에 필요한 LFS 파일만 받아와 clone 속도를 획기적으로 개선합니다. .gitattributes 파일에 대상 확장자 패턴을 등록하고 .git/hooks의 pre-commit 훅에 대용량 파일이 일반 커밋으로 올라오는 것을 자동 차단하는 검증 스크립트를 추가하여 팀 전체에 적용했습니다. 이제 신규 팀원은 전체 저장소를 1분 내에 클론할 수 있습니다.