Git 가비지 컬렉션 마스터하기: 최고 성능을 위한 가이드

git gc를 실행해야 하는 시점, 정리 대상, 활성 저장소에서 위험한 공격적 정리를 피하는 방법을 알아보세요.

Git 가비지 컬렉션 마스터하기: 최고 성능을 위한 가이드

Git 가비지 컬렉션은 저장소에 느슨한 객체, 오래된 도달 불가능한 커밋, 비효율적인 팩 파일이 영원히 쌓이는 것을 방지합니다. 저장소가 느리게 느껴지거나, 디스크 공간을 너무 많이 차지하거나, 리베이스와 브랜치 정리가 많았다면 git gc는 가장 먼저 이해해야 할 유지 관리 도구 중 하나입니다.

보통 매일 실행할 필요는 없습니다. Git은 특정 임계값에 도달하면 일반 명령 중에 자동 유지 관리를 실행합니다. 하지만 그것이 무엇을 하는지 알면 두 가지 일반적인 실수를 피하는 데 도움이 됩니다: 몇 달 동안 비대해진 저장소를 무시하거나, 영향을 이해하지 못한 채 공유 저장소에서 공격적인 정리를 실행하는 것입니다.

Git 가비지 컬렉션이 하는 일

Git은 데이터를 객체(커밋, 트리, 블롭, 태그)로 저장합니다. 새 객체는 .git/objects/ 아래에 느슨한 파일로 시작할 수 있습니다. 시간이 지나면서 Git은 많은 객체를 하나의 컴팩트한 팩 파일로 압축할 수 있습니다. 압축된 객체는 디스크를 더 효율적으로 사용하며 일반적으로 Git이 스캔하기에 더 빠릅니다.

git gc는 다음과 같은 여러 유지 관리 작업을 수행합니다:

  • 느슨한 객체를 팩 파일로 압축합니다.
  • 유용한 경우 기존 팩 파일을 통합합니다.
  • 제거하기에 충분히 오래된 도달 불가능한 객체를 제거합니다.
  • 중단된 작업으로 남은 임시 파일을 정리합니다.
  • 구성된 경우 최신 Git 설정에서 커밋 그래프 파일과 같은 보조 데이터를 업데이트합니다.

도달 불가능하다고 해서 즉시 삭제해도 안전하다는 의미는 아닙니다. 커밋은 리베이스, 수정, 리셋 또는 삭제된 브랜치 후에 도달 불가능해질 수 있습니다. Git은 일반적으로 최근에 도달 불가능해진 객체를 유예 기간 동안 유지하여 git reflog로 복구할 시간을 제공합니다.

정리하기 전에 저장소 크기 확인

추측 대신 저장소를 측정하는 것부터 시작하세요:

git count-objects -vH

유용한 필드로는 count, size, in-pack, packs, size-pack이 있습니다. 느슨한 객체 수가 많으면 일상적인 Git 작업 속도가 느려질 수 있습니다. size-pack이 크다는 것은 단순히 저장소에 실제 기록이 많거나, 큰 바이너리 파일이나 벤더 자산이 있다는 의미일 수 있습니다.

디스크 사용량을 직접 확인하려면 다음을 실행하세요:

du -sh .git

누군가 빌드 아티팩트나 대용량 아카이브를 커밋하여 .git이 거대하다면, 가비지 컬렉션만으로는 실제 문제를 해결하지 못할 수 있습니다. 향후 커밋에서 대용량 파일을 제거하거나, Git LFS로 이동하거나, 팀과 협의한 후 git filter-repo와 같은 도구로 기록을 다시 작성해야 할 수 있습니다.

일반 가비지 컬렉션 실행

일상적인 정리를 위해 다음을 사용하세요:

git gc

이것이 안전한 기본값입니다. Git이 어떤 유지 관리 작업을 수행할 가치가 있는지 결정하고 일반적인 정리 규칙을 따릅니다.

임계값이 필요하다고 판단할 때만 자동 유지 관리를 수행하도록 Git에 요청할 수 있습니다:

git gc --auto

대부분의 사용자는 --auto를 수동으로 호출할 필요가 없습니다. Git이 이미 백그라운드에서 이를 수행하기 때문입니다. 하지만 매번 전체 재패킹을 강제하지 않고 저비용 정리 패스를 원하는 스크립트에서는 여전히 유용합니다.

표준 유예 기간을 사용하여 오래된 도달 불가능한 객체를 제거하려면 다음을 실행하세요:

git gc --prune=now

--prune=now는 주의해서 사용하세요. git reflog가 찾는 데 도움이 될 수 있는 복구 지점을 제거할 수 있습니다. 복잡한 리베이스, 브랜치 삭제 또는 리셋 직후에는 이전 객체가 필요하지 않다고 확신하지 않는 한 사용을 피하세요.

--aggressive 사용 시 주의

git gc --aggressive는 Git이 객체 패킹을 최적화하는 데 더 많은 CPU 시간을 사용하도록 지시합니다:

git gc --aggressive

이것은 마법의 속도 버튼이 아닙니다. 많은 저장소에서 추가 작업은 일반 git gc에 비해 이점이 거의 없으며, 큰 기록에서는 오랜 시간이 걸릴 수 있습니다. 실제 저장소 크기나 성능 문제를 측정했고 유지 관리 기간을 감당할 수 있을 때만 사용하세요.

일상적인 작업에서는 일반 git gc를 선호하세요. 저장소에 정기적으로 공격적인 정리가 필요하다면, 더 깊은 문제는 종종 대용량 파일, 생성된 아티팩트, 또는 많은 도달 불가능한 기록을 생성하는 워크플로우입니다.

지속적인 관리를 위한 최신 Git 유지 관리 사용

최근 Git 버전에는 플랫폼 및 구성에 따라 프리페치, 커밋 그래프 업데이트, 증분 재패킹과 같은 백그라운드 작업을 예약할 수 있는 git maintenance가 포함되어 있습니다.

한 번 유지 관리를 실행하려면:

git maintenance run

사용자 계정에 대해 예약된 유지 관리를 활성화하려면:

git maintenance start

자동화에서 예약된 유지 관리를 사용하기 전에 Git 버전과 로컬 문서를 확인하세요. 정확한 스케줄러 통합은 운영 체제와 Git 빌드에 따라 다릅니다.

실용적인 정리 워크플로우

로컬 저장소의 안전한 정리 흐름은 다음과 같습니다:

git status
git count-objects -vH
git gc
git count-objects -vH

유지 관리 전에 작업 트리가 깨끗한지 확인하세요. Git은 로컬 변경 사항이 있어도 가비지 컬렉션을 실행할 수 있지만, 깨끗한 트리는 이후 문제 해결이 필요할 때 의심을 없앱니다.

서버의 공유 베어 저장소의 경우, 조용한 시간에 유지 관리를 예약하세요. 피크 CI 활동 중에는 무거운 재패킹을 피하세요. 클론, 페치, 푸시 작업이 디스크와 CPU를 놓고 경쟁할 수 있기 때문입니다.

가비지 컬렉션이 도움이 되지 않는 경우

가비지 컬렉션이 모든 느린 Git 저장소를 고칠 수는 없습니다. 기록에 여전히 도달 가능한 파일은 제거하지 않습니다. 활성 기록에 수년간의 대용량 자산이 포함된 경우 모노레포를 작게 만들지 않습니다. 손상된 저장소를 자체적으로 복구하지 않습니다.

일반 정리 후에도 성능이 여전히 좋지 않다면 다음 원인을 찾아보세요:

  • Git에 직접 커밋된 대용량 바이너리 파일.
  • 저장소에 추적된 너무 많은 생성된 파일.
  • 모든 작업에서 .git을 스캔하는 바이러스 백신 또는 파일 시스템 인덱싱.
  • 작업 트리를 호스팅하는 느린 네트워크 스토리지.
  • 스파스 체크아웃이 도움이 될 수 있는 매우 큰 작업 트리.

git gc를 저장소 위생의 대체재가 아닌 유지 관리로 사용하세요. 객체 수가 증가하면 일반 정리를 실행하고, 필요성을 측정하지 않는 한 공격적인 정리를 피하며, 큰 추적 아티팩트는 소스에서 해결해야 할 워크플로우 문제로 취급하세요.