부분 클론

Git 저장소가 커지면 히스토리를 다운로드해야 하는 양과 필요로 하는 디스크 공간이 많아져 작업이 어려워질 수 있습니다.

부분 클론 은 “Git이 저장소의 완전한 복사본 없이 작동할 수 있게 하는 성능 최적화입니다. 이 작업의 목표는 Git이 매우 큰 저장소를 더 잘 처리할 수 있도록 하는 것”입니다.

Git 2.22.0 이상이 필요합니다.

파일 크기로 필터링

Git에 대형 바이너리 파일을 저장하는 것은 일반적으로 권장되지 않습니다. 왜냐하면 추가된 모든 대형 파일은 클론하거나 변경 사항을 가져온 모든 사람이 다운로드하기 때문입니다. 이러한 다운로드는 느리고 문제가 있으며, 특히 느린이나 불안정한 인터넷 연결에서 작업하는 경우에는 더 그렇습니다.

파일 크기로 필터링을 사용하면 이 문제를 해결할 수 있는데, 문제가 되는 대형 파일을 클론하거나 가져오지 않습니다. Git이 누락된 파일을 만나면 필요할 때 다운로드합니다.

저장소를 복제할 때는 --filter=blob:limit=<size> 인수를 사용하세요. 예를들어, 1메가바이트보다 큰 파일을 제외하고 저장소를 복제하려면:

git clone --filter=blob:limit=1m git@gitlab.com:gitlab-com/www-gitlab-com.git

그러면 다음 출력이 생성됩니다:

'www-gitlab-com'으로 복제하는 중...
원격: 객체 나열하는 중: 832467, 완료.
원격: 객체 세는 중: 100% (832467/832467), 완료.
원격: 객체 압축하는 중: 100% (207226/207226), 완료.
원격: 총 832467 (델타 585563), 재사용 826624 (델타 580099), 팩 재사용 중 0
객체 받는 중: 100% (832467/832467), 2.34 GiB | 5.05 MiB/s, 완료.
델타 해결하고 있습니다: 100% (585563/585563), 완료.
원격: 객체 나열하는 중: 146, 완료.
원격: 객체 세는 중: 100% (146/146), 완료.
원격: 객체 압축하는 중: 100% (138/138), 완료.
원격: 총 146 (델타 8), 재사용 144 (델타 8), 팩 재사용 중 0
객체 받는 중: 100% (146/146), 471.45 MiB | 4.60 MiB/s, 완료.
델타 해결하고 있습니다: 100% (8/8), 완료.
파일 업데이트 중: 100% (13008/13008), 완료.
콘텐츠 필터링 중: 100% (3/3), 131.24 MiB | 4.65 MiB/s, 완료.

이 세부 정보는 Git이:

  1. 1메가바이트보다 큰 파일을 제외하고 저장소를 복제합니다.
  2. 기본 브랜치를 체크아웃하는 데 필요한 모든 누락된 대형 파일을 다운로드합니다.

브랜치를 변경하면 Git이 더 많은 누락된 파일을 다운로드할 수 있습니다.

객체 유형으로 필터링

수백만 개의 파일과 긴 히스토리가 있는 저장소의 경우, 모든 파일을 제외하고 git sparse-checkout를 사용하여 작업 복사본의 크기를 줄일 수 있습니다.

# 모든 파일을 제외하고 저장소 복제
$ git clone --filter=blob:none --sparse git@gitlab.com:gitlab-com/www-gitlab-com.git
'www-gitlab-com'으로 복제하는 중...
원격: 객체 나열하는 중: 678296, 완료.
원격: 객체 세는 중: 100% (678296/678296), 완료.
원격: 객체 압축하는 중: 100% (165915/165915), 완료.
원격: 총 678296 (델타 472342), 재사용 673292 (델타 467476), 팩 재사용 중 0
객체 받는 중: 100% (678296/678296), 81.06 MiB | 5.74 MiB/s, 완료.
델타 해결하고 있습니다: 100% (472342/472342), 완료.
원격: 객체 나열하는 중: 28, 완료.
원격: 객체 세는 중: 100% (28/28), 완료.
원격: 객체 압축하는 중: 100% (25/25), 완료.
원격: 총 28 (델타 0), 재사용 12 (델타 0), 팩 재사용 중 0
객체 받는 중: 100% (28/28), 140.29 KiB | 341.00 KiB/s, 완료.
파일 업데이트 중: 100% (28/28), 완료.

$ cd www-gitlab-com

$ git sparse-checkout set data --cone
원격: 객체 나열하는 중: 301, 완료.
원격: 객체 세는 중: 100% (301/301), 완료.
원격: 객체 압축하는 중: 100% (292/292), 완료.
원격: 총 301 (델타 16), 재사용 102 (델타 9), 팩 재사용 중 0
객체 받는 중: 100% (301/301), 1.15 MiB | 608.00 KiB/s, 완료.
델타 해결하고 있습니다: 100% (16/16), 완료.
파일 업데이트 중: 100% (302/302), 완료.

자세한 내용은 sparse-checkout에 대한 Git 설명서를 참조하세요.

파일 경로로 필터링하기

부분 복제 및 희소 체크아웃 사이의 심층 통합은 --filter=sparse:oid=<blob-ish> 필터 스펙을 통해 가능합니다. 이 필터링 모드는 .gitignore 파일과 유사한 형식을 사용하여 클론 및 가져오기 시 포함할 파일을 지정합니다.

경고: sparse 필터를 사용한 부분 복제는 여전히 실험적입니다. 클론 및 가져오기 시 Gitaly 자원 사용량을 늘리고 속도가 느릴 수 있습니다. 대신에 모든 블롭을 필터링하고 희소 체크아웃을 사용하세요(#filter-by-object-type), 왜냐하면 git-sparse-checkout을 사용하면 이러한 부분 복제 사용의 단점을 극복하고 간단해집니다.

더 자세한 내용은 rev-list-options에 대한 Git 설명서를 참조하세요.

  1. 필터 스펙을 만듭니다. 예를 들어, 루트 디렉토리의 각기 다른 하위 디렉토리에 많은 응용 프로그램이 있는 단일 저장소를 고려해 보십시오. 파일 shiny-app/.filterspec을 만듭니다:

    # 파일에 나열된 경로만 부분 복제를 수행할 때 다운로드받습니다
    # `--filter=sparse:oid=shiny-app/.gitfilterspec` 사용
    
    # git config --local core.sparsecheckout true로 희소 체크아웃을 구성하는 데 필요한 필터스펙을 명시적으로 포함
    # git show master:snazzy-app/.gitfilterspec >> .git/info/sparse-checkout
    shiny-app/.gitfilterspec
    
    # Shiny 앱
    shiny-app/
    
    # 의존성
    shimmery-app/
    shared-component-a/
    shared-component-b/
    
  2. 경로별로 클론 및 필터링합니다. clone 명령어를 사용하여 --filter=sparse:oid를 지원하면 희소 체크아웃과 완전히 통합되지 않았습니다.

    # 서버에 저장된 필터스펙을 사용하여 객체의 필터링된 집합을 클론합니다. 경고: 이 단계는 매우 느릴 수 있습니다!
    git clone --sparse --filter=sparse:oid=master:shiny-app/.gitfilterspec <url>
    
    # 선택 사항: 다운로드하지 않은 누락된 객체들이 있는지 확인합니다
    git rev-list --all --quiet --objects --missing=print | wc -l
    

    경고: bash, Zsh 등과 자동으로 Git 상태 정보를 표시하는 편집기 등에서 자주 git fetch를 실행하는 Git 통합이 있습니다. 전체 저장소를 가져옵니다. 이러한 통합을 비활성화하거나 다시 구성해야 할 수도 있습니다.

부분 복제 필터링 제거

부분 복제 필터링이 적용된 Git 저장소의 필터링을 제거할 수 있습니다. 필터링을 제거하려면:

  1. 필터에 의해 제외된 모든 것을 가져와서 저장소가 완전한지 확인합니다. git sparse-checkout을 사용한 경우 git sparse-checkout disable을 사용하여 비활성화합니다. 자세한 정보는 disable 설명서를 참조하세요.

    그런 다음 일반적인 fetch를 실행하여 저장소가 완전한지 확인하세요. 특히 git sparse-checkout을 사용하지 않을 때 누락된 객체를 가져올 필요가 있을 때는 다음 명령어를 사용할 수 있습니다:

    # 누락된 객체 보기
    git rev-list --objects --all --missing=print | grep -e '^\?'
    
    # '?' 문자 없이 누락된 객체 보기 (GNU grep이 필요합니다)
    git rev-list --objects --all --missing=print | grep -oP '^\?\K\w+'
    
    # 누락된 객체 가져오기
    git fetch origin $(git rev-list --objects --all --missing=print | grep -oP '^\?\K\w+')
    
    # 누락된 객체 수 보기
    git rev-list --objects --all --missing=print | grep -e '^\?' | wc -l
    
  2. 모든 것을 압축합니다. 예를 들어 git repack -a -d를 사용하여 수행할 수 있습니다. 이렇게 하면 .git/objects/pack/에 세 가지 파일만 남게 됩니다:
    • pack-<SHA1>.pack 파일
    • 해당하는 pack-<SHA1>.idx 파일
    • pack-<SHA1>.promisor 파일
  3. .promisor 파일을 삭제합니다. 위 단계를 거치면 비어 있고 삭제할 .promisor 파일이 하나만 남게됩니다.

  4. 부분 복제 구성을 제거합니다. 부분 복제 관련 구성 변수는 Git 구성 파일에서 제거되어야 합니다. 보통 다음 구성만 제거하면 됩니다:
    • remote.origin.promisor
    • remote.origin.partialclonefilter