가비지 콜렉트


깃은 저장소를 효율적으로 유지 관리하려고 가비지 콜렉트(garbage collect)를 지원합니다. 또 깃은 가비지를 효과적으로 관리할 수 있는 별도의 명령어를 제공합니다.


12.5.1 가비지


가비지(garbage)는 동적인 언어에서 메모리를 관리하려고 생성한 개념입니다. 깃은 이력을 추적할 때 객체의 생성과 변경을 반복합니다. 여러 번 처리 동작을 반복하면서 시간이 지남에 따라 연결 고리가 없는 고립된 객체들이 생겨 비효율적인 자원 상태가 됩니다.

고립된 객체들은 대표적으로 리셋(reset) 또는 리베이스(rebase) 등을 자주 할 때 발생합니다. 연결 고 리가 없는 객체들은 불필요하며, 용량만 차지하므로 정리해 주는 작업이 필요합니다.

깃의 커밋은 생성된 객체의 연결 고리를 설정하는 동작입니다. 커밋을 변경하면 새로운 객체로 연결 고리 를 재설정합니다. 하지만 기존에 연결된 객체들은 삭제하지 않고 유지합니다. 이러한 과정에서 불필요한 가비지가 생 성됩니다. 이처럼 객체는 향후 수동으로 커밋을 복구할 때 사용할 수 있기 때문에 유지합니다.


12.5.2 압축 관리


깃의 내부 원리는 SHA1 해시와 객체의 응용입니다. 파일 변경, 트리 구조, 커밋 등 대부분의 내 부 작업은 객체를 생성하고 연결하는 동작들입니다. 커밋들이 실행될 때 이러한 내부 동작으로 연 결 고리가 없는 객체가 수없이 생성됩니다. 깃 내부에 이러한 객체가 많아지면 저장소 용량도 커 지고, 객체도 빠르게 관리하기 어렵습니다. 깃은 이러한 객체를 줄이려고 생성된 객체를 압축합니 다. 즉, 깃은 연결 고리가 없는 객체들을 pack 파일 형태로 압축하여 저장합니다.


12.5.3 실행


깃은 가비지를 정리하려고 별도의 gc 명령어를 제공합니다. gc는 저수준 명령어로 garbage collect의 약어입니다. 깃에서 내부적으로 가비지 정리가 필요하다고 생각할 때, gc 명령어를 자 동으로 실행합니다. gc 명령어가 실행되면 오래된 객체들은 삭제하고 저장소 용량도 정리합니다. 자동 실행 외에 사용자가 직접 gc 명령어를 실행할 수 있습니다.

$ git gc --auto

gc 명령어를 실행할 때는 prune, repack, pack, rerere 등 하위 명령어와 같이 사용합니다. gc 명령어가 실행되면 객체를 압축하고 pack 파일 형태로 저장하거나 제거합니다.


12.5.4 refs 압축


gc 명령어는 객체의 압축과 refs를 같이 처리합니다. refs를 같이 압축하면 압축하기 전의 파일들 은 삭제됩니다. 그리고 새로운 .git/packed-refs 파일을 생성합니다.

이후 refs가 추가로 변경되면 압축한 packed-refs 값을 수정하지 않고 새로운 refs 파일을 생성 합니다. 즉, 압축한 이후에는 refs 파일이 2개가 되며, refs 파일이 여러 개 있으면 기본적으로 refs 안에 있는 파일을 먼저 찾습니다. 그리고 이후에 압축된 packed-refs 내용을 검색합니다.


12.5.5 환경 설정


gc 명령어의 동작은 환경 설정으로 제어할 수 있습니다.

  • gc.reflogExpire: reflog가 보존되는 기간을 설정합니다. 기본값은 90일입니다.
  • gc.reflogExpireUnreachable: 기본값은 30일입니다.
  • gc.aggressiveWindow: 창의 크기를 정합니다. 기본값은 250입니다.
  • gc.aggressiveDepth: 압축에 사용되는 매개변수이며, 기본값은 50입니다.
  • gc.pruneExpire: 저장소에 쓰는 다른 프로세스와 동시에 실행될 때 손상을 방지합니다.
  • gc.worktreePruneExpire: 유예 기간을 설정할 수 있습니다.

gc 명령어의 동작은 gc.auto 항목으로 자동 설정을 허용하지 않을 수도 있고, gc.autopacklimit를 사용하여 최대 압축 숫자를 제어할 수도 있습니다.

깃교과서

버전 관리 시스템의 이해와 설치부터 커밋, 브랜치, 임시 처리, 병합, 복귀, 서브모듈, 태그까지
깃, 소스트리, 깃허브로 실습하며 기본기를 탄탄하게 다진다!