InfoGrab Docs

저장소 크기

요약

Git 저장소의 크기는 성능과 스토리지 비용에 상당한 영향을 미칠 수 있습니다. 프로젝트 개요 페이지는 저장소 파일, 아티팩트, LFS를 포함한 저장소의 모든 파일 크기를 표시합니다. 저장소 크기는 저장소의 모든 파일의 누적 크기를 계산하여 결정됩니다.

Git 저장소의 크기는 성능과 스토리지 비용에 상당한 영향을 미칠 수 있습니다. 압축, 하우스키핑, 기타 요인으로 인해 인스턴스마다 약간 다를 수 있습니다.

크기 계산#

프로젝트 개요 페이지는 저장소 파일, 아티팩트, LFS를 포함한 저장소의 모든 파일 크기를 표시합니다. 이 크기는 15분마다 업데이트됩니다.

저장소 크기는 저장소의 모든 파일의 누적 크기를 계산하여 결정됩니다. 이 계산은 저장소의 해시된 스토리지 경로에서 du --summarize --bytes를 실행하는 것과 유사합니다.

크기 및 스토리지 제한#

관리자는 GitLab Self-Managed에 대한 저장소 크기 제한을 설정할 수 있습니다. GitLab SaaS의 경우 크기 제한은 사전 정의되어 있습니다.

프로젝트가 크기 제한에 도달하면 푸시, 머지 리퀘스트 만들기, LFS 객체 업로드와 같은 특정 작업이 제한됩니다.

Git 기록 재작성 전#

저장소에서 Git 기록을 재작성하고 데이터를 제거하기 전에 다음 섹션의 정보를 고려해야 합니다.

로컬 클론을 변경해야 함#

저장소 클론이 있는 모든 사람은 다음 중 하나를 해야 합니다:

  • 로컬 복사본을 삭제하고 저장소의 새 복사본을 클론합니다.
  • 모든 원격 변경 사항을 페치하고 진행 중인 모든 작업이 그 위에 리베이스되도록 합니다.

올바르게 수행되지 않으면 로컬 변경 사항을 푸시하는 사용자가 삭제하려 했던 파일을 복구할 수 있습니다.

실행 중인 파이프라인이 정리 실패를 일으킬 수 있음#

정리 중에 여전히 파이프라인이 실행 중이면 저장소와 상호 작용하여 정리가 제대로 작동하지 않을 수 있습니다.

가비지 컬렉션 유예 기간#

GitLab은 30분의 유예 기간으로 Git 가비지 컬렉션을 실행합니다. 이 프로세스는 다음 두 조건을 모두 충족하는 객체를 정리합니다:

  • 어떤 참조에서도 도달할 수 없는 것.
  • 최소 30분 이상 된 것.

제거하려는 데이터가 어떤 커밋에서도 도달 가능하거나 30분 미만인 경우 Git 가비지 컬렉션이 제거하지 않습니다.

결과적으로 하우스키핑을 실행한 후 Prune unreachable objects를 선택하기 전에 최소 30분을 기다려야 합니다.

포크된 프로젝트에서 기록을 재작성할 수 없음#

내장 메서드는 포크된 저장소에서 사용할 수 없습니다. 포크 전체에 걸쳐 GitLab 객체가 저장되는 방식으로 인해 Git이 포크 간에 공유되는 객체를 가비지 컬렉션하는 것이 불가능합니다.

해결 방법: 프로젝트 아카이브#

정리 전에 아카이브하면 저장소가 읽기 전용이 됩니다. 이를 통해 정리가 진행되는 동안 아무도 변경하지 않을 것이 보장됩니다.

저장소를 아카이브하면 포크 관계도 제거됩니다. 이를 통해 데이터를 정리할 수 있습니다. 그러나 데이터가 포크로 가져왔다면 거기서도 정리가 이루어져야 합니다.

저장소 크기를 줄이는 방법#

저장소 크기를 줄이기 위해 다음 방법을 사용할 수 있습니다:

  • 기록에서 파일 제거: Git 기록 전체에서 대용량 파일을 제거합니다.
  • 저장소 정리: 내부 Git 참조와 참조되지 않은 객체를 제거합니다.
  • blob 제거: 민감하거나 기밀 정보가 포함된 blob을 영구적으로 삭제합니다.

저장소 크기를 줄이기 전에 저장소의 전체 백업을 만들어야 합니다. 이러한 방법은 되돌릴 수 없으며 프로젝트의 기록과 데이터에 영향을 미칠 수 있습니다.

사용 가능한 방법 중 하나로 저장소 크기를 줄일 때 프로젝트에 대한 액세스를 차단할 필요가 없습니다. 프로젝트가 사용자에게 계속 액세스 가능한 상태에서 이러한 작업을 수행할 수 있습니다. 이러한 방법은 알려진 성능 영향이 없으며 다운타임을 일으키지 않습니다. 그러나 사용자에게 미치는 잠재적 영향을 최소화하기 위해 활동이 적은 시간에 이러한 작업을 수행해야 합니다.

저장소 기록에서 파일 제거#

git filter-repo를 사용하여 파일을 제거하면 Git 기록에서 대용량 파일을 제거할 수 있습니다. 비밀번호나 키와 같은 민감한 데이터를 제거하는 데 이 방법을 사용하지 마세요. 대신 blob 제거 또는 텍스트 수정을 사용합니다.

이 프로세스는:

  • 전체 Git 기록을 수정합니다.
  • 열린 머지 리퀘스트에 영향을 미칠 수 있습니다.
  • 기존 파이프라인에 영향을 미칠 수 있습니다.
  • 로컬 저장소의 재클론이 필요합니다.
  • LFS 객체에 영향을 미치지 않습니다.
  • 커밋 서명을 지정하지 않습니다.
  • 되돌릴 수 없습니다.
Note

파일 콘텐츠를 포함한 커밋에 대한 정보는 데이터베이스에 캐시되며 저장소에서 제거된 후에도 계속 표시됩니다.

저장소 정리#

이 방법을 사용하여 저장소에서 내부 Git 참조와 참조되지 않은 객체를 제거합니다. 민감한 데이터를 제거하는 데 이 방법을 사용하지 마세요. 대신 blob 제거를 사용합니다.

이 프로세스는:

  • git gc --prune=30.minutes.ago를 실행하여 참조되지 않은 객체를 제거합니다.
  • 사용되지 않는 LFS 객체의 링크를 해제하여 스토리지 공간을 확보합니다.
  • 디스크의 저장소 크기를 재계산합니다.
  • 되돌릴 수 없습니다.
Warning

내부 Git 참조를 제거하면 관련 머지 리퀘스트 커밋, 파이프라인, 변경 세부 정보를 사용할 수 없게 됩니다.

전제 조건:

  • 제거할 객체 목록. git filter-repo를 사용하여 commit-map 파일에 객체 목록을 생성합니다.

저장소를 정리하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.

  2. Settings > Repository로 이동합니다.

  3. Repository maintenance를 확장합니다.

  4. 제거할 객체 목록을 업로드합니다. 예를 들어 filter-repo 디렉토리의 commit-map 파일입니다.

    commit-map 파일이 너무 큰 경우 백그라운드 정리 프로세스가 타임아웃되어 실패할 수 있습니다. 결과적으로 예상대로 저장소 크기가 줄어들지 않습니다. 이 문제를 해결하려면 파일을 분할하여 부분적으로 업로드합니다. 20000으로 시작하여 필요에 따라 줄입니다. 예를 들어:

    split -l 20000 filter-repo/commit-map filter-repo/commit-map-
    
  5. Start cleanup을 선택합니다.

정리가 완료된 후 GitLab은 재계산된 저장소 크기가 포함된 이메일 알림을 보냅니다.

저장소에서 데이터 제거#

저장소에서 민감하거나 기밀 데이터를 제거하려면 다음 방법 중 하나를 사용합니다:

  • 파일을 완전히 제거하려면 blob 제거를 합니다.
  • 파일을 유지하되 기밀 텍스트를 대체 텍스트 ***REMOVED***로 교체하려면 텍스트 수정을 합니다.

blob 제거#

히스토리

Git 바이너리 대형 객체(blob)는 메타데이터 없이 파일 콘텐츠를 저장합니다. 각 blob에는 저장소의 파일의 특정 버전을 나타내는 고유한 SHA 해시가 있습니다.

이 방법을 사용하여 민감하거나 기밀 정보가 포함된 blob을 영구적으로 삭제합니다.

이 프로세스는:

  • Git 기록을 재작성합니다.
  • 커밋 서명을 삭제합니다.
  • 열린 머지 리퀘스트가 머지에 실패하게 하여 수동 리베이스가 필요할 수 있습니다.
  • 이전 커밋 SHA를 참조하는 파이프라인이 중단될 수 있습니다.
  • 이전 커밋 기록을 기반으로 한 기존 태그와 브랜치에 영향을 미칠 수 있습니다.
  • 로컬 저장소의 재클론이 필요합니다.
  • 되돌릴 수 없습니다.
Note

대체 문자열 ***REMOVED***로 문자열을 교체할 수도 있습니다. 자세한 내용은 저장소에서 텍스트 수정을 참조하세요.

전제 조건:

  • 프로젝트의 Owner 역할이 있어야 합니다.
  • 제거할 객체 ID 목록.
  • 프로젝트가 다음이 아니어야 합니다:
    • 공개 업스트림 프로젝트의 포크.
    • 다운스트림 포크가 있는 공개 업스트림 프로젝트.
Note

blob 제거가 성공하도록 하려면 프로세스 중에 저장소 액세스를 일시적으로 제한하는 것을 고려하세요. blob 제거 중에 푸시된 새 커밋이 작업 실패를 일으킬 수 있습니다.

저장소에서 blob을 제거하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. Settings > Repository를 선택합니다.
  3. Repository maintenance를 확장합니다.
  4. Remove blobs를 선택합니다.
  5. 제거할 blob ID 목록을 입력하며 각 ID는 별도의 줄에 입력합니다.
  6. Remove blobs를 선택합니다.
  7. 확인 대화 상자에서 프로젝트 경로를 입력합니다.
  8. Yes, remove blobs를 선택합니다.
  9. blob 제거가 완료될 때까지 기다린 후 계속합니다:
    • 이메일 알림이 활성화된 경우 저장소 기록 재작성이 완료되었다는 이메일을 받을 때까지 기다립니다.
    • 이메일 알림이 활성화되지 않은 경우 최소 5분을 기다립니다.
  10. 왼쪽 사이드바에서 Settings > General을 선택합니다.
  11. Advanced 레이블이 지정된 섹션을 확장합니다.
  12. Run housekeeping을 선택합니다. 작업이 완료될 때까지 최소 30분을 기다립니다.
  13. 동일한 Settings > General > Advanced 섹션에서 Prune unreachable objects를 선택합니다. 이 작업은 완료하는 데 약 5-10분이 걸립니다.
Note

민감한 정보가 포함된 프로젝트가 포크된 경우 하우스키핑 작업이 이 프로세스를 완료하지 않고 성공할 수 있습니다. 하우스키핑은 포크된 데이터가 포함된 특수 객체 풀 저장소의 무결성을 유지해야 합니다. 도움이 필요하면 GitLab 지원에 문의하세요.

객체 ID 목록 가져오기#

blob을 제거하려면 제거할 객체 목록이 필요합니다. 이 ID를 가져오려면 ls-tree 명령을 사용하거나 저장소 API 저장소 트리 목록 엔드포인트를 사용합니다. 다음 지침은 ls-tree 명령을 사용합니다.

전제 조건:

  • 저장소가 로컬 시스템에 클론되어 있어야 합니다.

주어진 커밋이나 브랜치에서 크기별로 정렬된 blob 목록을 가져오려면:

  1. 터미널을 열고 저장소 디렉토리로 이동합니다.

  2. 다음 명령을 실행합니다:

    git ls-tree -r -t --long --full-name  | sort -nk 4
    

    예시 출력:

    100644 blob 8150ee86f923548d376459b29afecbe8495514e9  133508 doc/howto/img/remote-development-new-workspace-button.png
    100644 blob cde4360b3d3ee4f4c04c998d43cfaaf586f09740  214231 doc/howto/img/dependency_proxy_macos_config_new.png
    100644 blob 2ad0e839a709e73a6174e78321e87021b20be445  216452 doc/howto/img/gdk-in-gitpod.jpg
    100644 blob 115dd03fc0828a9011f012abbc58746f7c587a05  242304 doc/howto/img/gitpod-button-repository.jpg
    100644 blob c41ebb321a6a99f68ee6c353dd0ed29f52c1dc80  491158 doc/howto/img/dependency_proxy_macos_config.png
    

    출력의 세 번째 열은 blob의 객체 ID입니다. 예: 8150ee86f923548d376459b29afecbe8495514e9.

저장소에서 텍스트 수정#

히스토리
  • GitLab 17.1에서 rewrite_history_ui라는 플래그와 함께 도입됨. 기본적으로 비활성화. GitLab 팀원은 이 기밀 이슈에서 더 많은 정보를 볼 수 있습니다: https://gitlab.com/gitlab-org/gitlab/-/issues/450701.
  • GitLab 17.2에서 기밀 이슈 https://gitlab.com/gitlab-org/gitlab/-/issues/462999에서 GitLab.com에서 활성화됨.
  • GitLab 17.3에서 기밀 이슈 https://gitlab.com/gitlab-org/gitlab/-/issues/462999에서 GitLab Self-Managed 및 GitLab Dedicated에서 활성화됨.
  • GitLab 17.9에서 기밀 이슈 https://gitlab.com/gitlab-org/gitlab/-/issues/472018에서 일반 공개됨. 기능 플래그 rewrite_history_ui 제거됨.

실수로 커밋된 민감하거나 기밀 정보를 영구적으로 삭제하여 저장소 기록에서 더 이상 액세스할 수 없도록 합니다. 문자열 목록을 ***REMOVED***로 교체합니다.

Warning

이 작업은 되돌릴 수 없습니다. 기록을 재작성하고 하우스키핑을 실행하면 변경 사항은 영구적입니다.

GitLab에서 파일을 수정하면 노출된 비밀 정보가 제거되지만 다음도 수행됩니다:

  • Git 기록을 재작성합니다. 이전 커밋 기록을 기반으로 한 기존 태그와 브랜치가 올바르게 작동하지 않을 수 있습니다.
  • 파괴적입니다. 기존 로컬 클론은 업데이트된 저장소와 호환되지 않으며 재클론해야 합니다.
  • 수정이 콘텐츠를 업데이트하기 때문에 커밋 해시를 업데이트합니다.
  • 재작성 프로세스 중에 커밋 서명을 삭제합니다.
  • 커밋 해시에 의존하는 기능을 중단시키며 다음을 포함합니다:
    • 열린 머지 리퀘스트. 열린 머지 리퀘스트가 머지에 실패하고 수동 리베이스가 필요할 수 있습니다.
    • 이전 커밋에 대한 링크로, 404 오류가 발생합니다.
  • 이전 커밋 SHA를 참조하는 파이프라인이 중단되어 재구성이 필요할 수 있습니다.

저장소 무결성을 위해 대신 다음을 수행해야 합니다:

이 방법은:

  • 향후 비밀 정보 유출을 사전에 방지합니다.
  • 보안 규정 준수를 보장하면서 Git 기록을 유지합니다.

자세한 내용은 시크릿 푸시 보호를 참조하세요.

또는 저장소에서 특정 파일을 완전히 삭제하려면 blob 제거를 참조하세요.

전제 조건:

  • 프로젝트의 Owner 역할이 있어야 합니다.

저장소에서 텍스트를 수정하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. Settings > Repository를 선택합니다.
  3. Repository maintenance를 확장합니다.
  4. Redact text를 선택합니다.
  5. 드로어에서 수정할 텍스트를 입력합니다. 정규 표현식과 글로브 패턴이 허용됩니다.
  6. Redact matching strings를 선택합니다.
  7. 확인 대화 상자에서 프로젝트 경로를 입력합니다.
  8. Yes, redact matching strings를 선택합니다.
  9. 왼쪽 사이드바에서 Settings > General을 선택합니다.
  10. Advanced를 확장합니다.
  11. Run housekeeping을 선택합니다. 작업이 완료될 때까지 최소 30분을 기다립니다.
  12. 동일한 Settings > General > Advanced 섹션에서 Prune unreachable objects를 선택합니다. 이 작업은 완료하는 데 약 5-10분이 걸립니다.
Note

민감한 정보가 포함된 프로젝트가 포크된 경우 하우스키핑 작업이 이 수정 프로세스를 완료하지 못해 포크된 데이터가 포함된 특수 객체 풀 저장소의 무결성을 유지할 수 있습니다 (해당 데이터를 포함하는). 도움이 필요하면 GitLab 지원에 문의하세요.

트러블슈팅#

이 섹션에는 발생할 수 있는 문제에 대한 해결책이 있습니다.

GUI에 표시된 잘못된 저장소 통계#

GitLab 인터페이스에 표시된 저장소 크기나 커밋 수가 내보낸 .tar.gz나 로컬 저장소와 다른 경우:

  1. GitLab 관리자에게 Rails 콘솔을 사용하여 강제 업데이트를 요청합니다.

  2. 관리자는 다음 명령을 실행해야 합니다:

    p = Project.find_by_full_path('<namespace>/<project>')
    p.statistics.refresh!
    
  3. 프로젝트 통계를 지우고 재계산을 트리거하려면:

    p.repository.expire_all_method_caches
    UpdateProjectStatisticsWorker.perform_async(p.id, ["commit_count","repository_size","storage_size","lfs_objects_size","container_registry_size"])
    
  4. 총 아티팩트 스토리지 공간을 확인하려면:

    builds_with_artifacts = p.builds.with_downloadable_artifacts.all
    
    artifact_storage = 0
    builds_with_artifacts.find_each do |build|
      artifact_storage += build.artifacts_size
    end
    
    puts "#{artifact_storage} bytes"
    

정리 후 공간이 확보되지 않음#

저장소 정리 프로세스를 완료했지만 스토리지 사용량이 변경되지 않은 경우:

  • 도달할 수 없는 객체는 2주 유예 기간 동안 저장소에 남아 있습니다.
  • 이러한 객체는 내보내기에 포함되지 않지만 여전히 파일 시스템 공간을 차지합니다.
  • 2주 후에 이러한 객체가 자동으로 정리되어 스토리지 사용량 통계가 업데이트됩니다.
  • 이 프로세스를 가속화하려면 관리자에게 'Prune Unreachable Objects' 하우스키핑 작업을 실행해 달라고 요청합니다.

blob이 제거되지 않음#

blob이 성공적으로 제거되면 GitLab은 프로젝트 감사 로그에 항목을 추가하고 작업을 시작한 사람에게 이메일 알림을 보냅니다.

blob 제거에 실패하면 GitLab은 제목 <project_name> | Project history rewrite failure로 시작자에게 이메일 알림을 보냅니다. 이메일 본문에는 전체 오류 메시지가 포함됩니다.

가능한 오류 및 해결 방법:

  • validating object ID: invalid object ID: 객체 ID 목록에 구문 오류 또는 잘못된 객체 ID가 포함되어 있습니다. 해결하려면:
    1. 객체 ID 목록을 재생성합니다.
    2. blob 제거 단계를 다시 실행합니다.
  • source repository checksum altered: blob 제거 프로세스 중에 누군가가 커밋을 푸시한 경우 발생합니다. 해결하려면:
    1. 저장소에 대한 모든 푸시를 일시적으로 차단합니다.
    2. blob 제거 단계를 다시 실행합니다.
    3. 프로세스가 성공적으로 완료된 후 푸시를 다시 활성화합니다.

저장소 크기 제한 도달#

저장소 크기 제한에 도달한 경우:

  • 일부 데이터를 제거하고 새 커밋을 만들어 보세요.
  • 성공하지 못하면 일부 blob을 Git LFS로 이동하거나 기록에서 오래된 의존성 업데이트를 제거하는 것을 고려합니다.
  • 여전히 변경 사항을 푸시할 수 없으면 GitLab 관리자에게 연락하여 일시적으로 프로젝트의 제한을 늘려 달라고 요청합니다.
  • 최후의 수단으로 새 프로젝트를 만들고 데이터를 마이그레이션합니다.
Note

새 커밋에서 파일을 삭제해도 저장소 크기가 즉시 줄어들지 않습니다. 이전 커밋과 blob이 여전히 존재하기 때문입니다. 크기를 효과적으로 줄이려면 git filter-repo와 같은 도구를 사용하여 기록을 재작성해야 합니다.

저장소 크기

Tier: Free, Premium, Ultimate
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
원문 보기
요약

Git 저장소의 크기는 성능과 스토리지 비용에 상당한 영향을 미칠 수 있습니다. 프로젝트 개요 페이지는 저장소 파일, 아티팩트, LFS를 포함한 저장소의 모든 파일 크기를 표시합니다. 저장소 크기는 저장소의 모든 파일의 누적 크기를 계산하여 결정됩니다.

Git 저장소의 크기는 성능과 스토리지 비용에 상당한 영향을 미칠 수 있습니다. 압축, 하우스키핑, 기타 요인으로 인해 인스턴스마다 약간 다를 수 있습니다.

크기 계산#

프로젝트 개요 페이지는 저장소 파일, 아티팩트, LFS를 포함한 저장소의 모든 파일 크기를 표시합니다. 이 크기는 15분마다 업데이트됩니다.

저장소 크기는 저장소의 모든 파일의 누적 크기를 계산하여 결정됩니다. 이 계산은 저장소의 해시된 스토리지 경로에서 du --summarize --bytes를 실행하는 것과 유사합니다.

크기 및 스토리지 제한#

관리자는 GitLab Self-Managed에 대한 저장소 크기 제한을 설정할 수 있습니다. GitLab SaaS의 경우 크기 제한은 사전 정의되어 있습니다.

프로젝트가 크기 제한에 도달하면 푸시, 머지 리퀘스트 만들기, LFS 객체 업로드와 같은 특정 작업이 제한됩니다.

Git 기록 재작성 전#

저장소에서 Git 기록을 재작성하고 데이터를 제거하기 전에 다음 섹션의 정보를 고려해야 합니다.

로컬 클론을 변경해야 함#

저장소 클론이 있는 모든 사람은 다음 중 하나를 해야 합니다:

  • 로컬 복사본을 삭제하고 저장소의 새 복사본을 클론합니다.
  • 모든 원격 변경 사항을 페치하고 진행 중인 모든 작업이 그 위에 리베이스되도록 합니다.

올바르게 수행되지 않으면 로컬 변경 사항을 푸시하는 사용자가 삭제하려 했던 파일을 복구할 수 있습니다.

실행 중인 파이프라인이 정리 실패를 일으킬 수 있음#

정리 중에 여전히 파이프라인이 실행 중이면 저장소와 상호 작용하여 정리가 제대로 작동하지 않을 수 있습니다.

가비지 컬렉션 유예 기간#

GitLab은 30분의 유예 기간으로 Git 가비지 컬렉션을 실행합니다. 이 프로세스는 다음 두 조건을 모두 충족하는 객체를 정리합니다:

  • 어떤 참조에서도 도달할 수 없는 것.
  • 최소 30분 이상 된 것.

제거하려는 데이터가 어떤 커밋에서도 도달 가능하거나 30분 미만인 경우 Git 가비지 컬렉션이 제거하지 않습니다.

결과적으로 하우스키핑을 실행한 후 Prune unreachable objects를 선택하기 전에 최소 30분을 기다려야 합니다.

포크된 프로젝트에서 기록을 재작성할 수 없음#

내장 메서드는 포크된 저장소에서 사용할 수 없습니다. 포크 전체에 걸쳐 GitLab 객체가 저장되는 방식으로 인해 Git이 포크 간에 공유되는 객체를 가비지 컬렉션하는 것이 불가능합니다.

해결 방법: 프로젝트 아카이브#

정리 전에 아카이브하면 저장소가 읽기 전용이 됩니다. 이를 통해 정리가 진행되는 동안 아무도 변경하지 않을 것이 보장됩니다.

저장소를 아카이브하면 포크 관계도 제거됩니다. 이를 통해 데이터를 정리할 수 있습니다. 그러나 데이터가 포크로 가져왔다면 거기서도 정리가 이루어져야 합니다.

저장소 크기를 줄이는 방법#

저장소 크기를 줄이기 위해 다음 방법을 사용할 수 있습니다:

  • 기록에서 파일 제거: Git 기록 전체에서 대용량 파일을 제거합니다.
  • 저장소 정리: 내부 Git 참조와 참조되지 않은 객체를 제거합니다.
  • blob 제거: 민감하거나 기밀 정보가 포함된 blob을 영구적으로 삭제합니다.

저장소 크기를 줄이기 전에 저장소의 전체 백업을 만들어야 합니다. 이러한 방법은 되돌릴 수 없으며 프로젝트의 기록과 데이터에 영향을 미칠 수 있습니다.

사용 가능한 방법 중 하나로 저장소 크기를 줄일 때 프로젝트에 대한 액세스를 차단할 필요가 없습니다. 프로젝트가 사용자에게 계속 액세스 가능한 상태에서 이러한 작업을 수행할 수 있습니다. 이러한 방법은 알려진 성능 영향이 없으며 다운타임을 일으키지 않습니다. 그러나 사용자에게 미치는 잠재적 영향을 최소화하기 위해 활동이 적은 시간에 이러한 작업을 수행해야 합니다.

저장소 기록에서 파일 제거#

git filter-repo를 사용하여 파일을 제거하면 Git 기록에서 대용량 파일을 제거할 수 있습니다. 비밀번호나 키와 같은 민감한 데이터를 제거하는 데 이 방법을 사용하지 마세요. 대신 blob 제거 또는 텍스트 수정을 사용합니다.

이 프로세스는:

  • 전체 Git 기록을 수정합니다.
  • 열린 머지 리퀘스트에 영향을 미칠 수 있습니다.
  • 기존 파이프라인에 영향을 미칠 수 있습니다.
  • 로컬 저장소의 재클론이 필요합니다.
  • LFS 객체에 영향을 미치지 않습니다.
  • 커밋 서명을 지정하지 않습니다.
  • 되돌릴 수 없습니다.
Note

파일 콘텐츠를 포함한 커밋에 대한 정보는 데이터베이스에 캐시되며 저장소에서 제거된 후에도 계속 표시됩니다.

저장소 정리#

이 방법을 사용하여 저장소에서 내부 Git 참조와 참조되지 않은 객체를 제거합니다. 민감한 데이터를 제거하는 데 이 방법을 사용하지 마세요. 대신 blob 제거를 사용합니다.

이 프로세스는:

  • git gc --prune=30.minutes.ago를 실행하여 참조되지 않은 객체를 제거합니다.
  • 사용되지 않는 LFS 객체의 링크를 해제하여 스토리지 공간을 확보합니다.
  • 디스크의 저장소 크기를 재계산합니다.
  • 되돌릴 수 없습니다.
Warning

내부 Git 참조를 제거하면 관련 머지 리퀘스트 커밋, 파이프라인, 변경 세부 정보를 사용할 수 없게 됩니다.

전제 조건:

  • 제거할 객체 목록. git filter-repo를 사용하여 commit-map 파일에 객체 목록을 생성합니다.

저장소를 정리하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.

  2. Settings > Repository로 이동합니다.

  3. Repository maintenance를 확장합니다.

  4. 제거할 객체 목록을 업로드합니다. 예를 들어 filter-repo 디렉토리의 commit-map 파일입니다.

    commit-map 파일이 너무 큰 경우 백그라운드 정리 프로세스가 타임아웃되어 실패할 수 있습니다. 결과적으로 예상대로 저장소 크기가 줄어들지 않습니다. 이 문제를 해결하려면 파일을 분할하여 부분적으로 업로드합니다. 20000으로 시작하여 필요에 따라 줄입니다. 예를 들어:

    split -l 20000 filter-repo/commit-map filter-repo/commit-map-
    
  5. Start cleanup을 선택합니다.

정리가 완료된 후 GitLab은 재계산된 저장소 크기가 포함된 이메일 알림을 보냅니다.

저장소에서 데이터 제거#

저장소에서 민감하거나 기밀 데이터를 제거하려면 다음 방법 중 하나를 사용합니다:

  • 파일을 완전히 제거하려면 blob 제거를 합니다.
  • 파일을 유지하되 기밀 텍스트를 대체 텍스트 ***REMOVED***로 교체하려면 텍스트 수정을 합니다.

blob 제거#

히스토리

Git 바이너리 대형 객체(blob)는 메타데이터 없이 파일 콘텐츠를 저장합니다. 각 blob에는 저장소의 파일의 특정 버전을 나타내는 고유한 SHA 해시가 있습니다.

이 방법을 사용하여 민감하거나 기밀 정보가 포함된 blob을 영구적으로 삭제합니다.

이 프로세스는:

  • Git 기록을 재작성합니다.
  • 커밋 서명을 삭제합니다.
  • 열린 머지 리퀘스트가 머지에 실패하게 하여 수동 리베이스가 필요할 수 있습니다.
  • 이전 커밋 SHA를 참조하는 파이프라인이 중단될 수 있습니다.
  • 이전 커밋 기록을 기반으로 한 기존 태그와 브랜치에 영향을 미칠 수 있습니다.
  • 로컬 저장소의 재클론이 필요합니다.
  • 되돌릴 수 없습니다.
Note

대체 문자열 ***REMOVED***로 문자열을 교체할 수도 있습니다. 자세한 내용은 저장소에서 텍스트 수정을 참조하세요.

전제 조건:

  • 프로젝트의 Owner 역할이 있어야 합니다.
  • 제거할 객체 ID 목록.
  • 프로젝트가 다음이 아니어야 합니다:
    • 공개 업스트림 프로젝트의 포크.
    • 다운스트림 포크가 있는 공개 업스트림 프로젝트.
Note

blob 제거가 성공하도록 하려면 프로세스 중에 저장소 액세스를 일시적으로 제한하는 것을 고려하세요. blob 제거 중에 푸시된 새 커밋이 작업 실패를 일으킬 수 있습니다.

저장소에서 blob을 제거하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. Settings > Repository를 선택합니다.
  3. Repository maintenance를 확장합니다.
  4. Remove blobs를 선택합니다.
  5. 제거할 blob ID 목록을 입력하며 각 ID는 별도의 줄에 입력합니다.
  6. Remove blobs를 선택합니다.
  7. 확인 대화 상자에서 프로젝트 경로를 입력합니다.
  8. Yes, remove blobs를 선택합니다.
  9. blob 제거가 완료될 때까지 기다린 후 계속합니다:
    • 이메일 알림이 활성화된 경우 저장소 기록 재작성이 완료되었다는 이메일을 받을 때까지 기다립니다.
    • 이메일 알림이 활성화되지 않은 경우 최소 5분을 기다립니다.
  10. 왼쪽 사이드바에서 Settings > General을 선택합니다.
  11. Advanced 레이블이 지정된 섹션을 확장합니다.
  12. Run housekeeping을 선택합니다. 작업이 완료될 때까지 최소 30분을 기다립니다.
  13. 동일한 Settings > General > Advanced 섹션에서 Prune unreachable objects를 선택합니다. 이 작업은 완료하는 데 약 5-10분이 걸립니다.
Note

민감한 정보가 포함된 프로젝트가 포크된 경우 하우스키핑 작업이 이 프로세스를 완료하지 않고 성공할 수 있습니다. 하우스키핑은 포크된 데이터가 포함된 특수 객체 풀 저장소의 무결성을 유지해야 합니다. 도움이 필요하면 GitLab 지원에 문의하세요.

객체 ID 목록 가져오기#

blob을 제거하려면 제거할 객체 목록이 필요합니다. 이 ID를 가져오려면 ls-tree 명령을 사용하거나 저장소 API 저장소 트리 목록 엔드포인트를 사용합니다. 다음 지침은 ls-tree 명령을 사용합니다.

전제 조건:

  • 저장소가 로컬 시스템에 클론되어 있어야 합니다.

주어진 커밋이나 브랜치에서 크기별로 정렬된 blob 목록을 가져오려면:

  1. 터미널을 열고 저장소 디렉토리로 이동합니다.

  2. 다음 명령을 실행합니다:

    git ls-tree -r -t --long --full-name  | sort -nk 4
    

    예시 출력:

    100644 blob 8150ee86f923548d376459b29afecbe8495514e9  133508 doc/howto/img/remote-development-new-workspace-button.png
    100644 blob cde4360b3d3ee4f4c04c998d43cfaaf586f09740  214231 doc/howto/img/dependency_proxy_macos_config_new.png
    100644 blob 2ad0e839a709e73a6174e78321e87021b20be445  216452 doc/howto/img/gdk-in-gitpod.jpg
    100644 blob 115dd03fc0828a9011f012abbc58746f7c587a05  242304 doc/howto/img/gitpod-button-repository.jpg
    100644 blob c41ebb321a6a99f68ee6c353dd0ed29f52c1dc80  491158 doc/howto/img/dependency_proxy_macos_config.png
    

    출력의 세 번째 열은 blob의 객체 ID입니다. 예: 8150ee86f923548d376459b29afecbe8495514e9.

저장소에서 텍스트 수정#

히스토리
  • GitLab 17.1에서 rewrite_history_ui라는 플래그와 함께 도입됨. 기본적으로 비활성화. GitLab 팀원은 이 기밀 이슈에서 더 많은 정보를 볼 수 있습니다: https://gitlab.com/gitlab-org/gitlab/-/issues/450701.
  • GitLab 17.2에서 기밀 이슈 https://gitlab.com/gitlab-org/gitlab/-/issues/462999에서 GitLab.com에서 활성화됨.
  • GitLab 17.3에서 기밀 이슈 https://gitlab.com/gitlab-org/gitlab/-/issues/462999에서 GitLab Self-Managed 및 GitLab Dedicated에서 활성화됨.
  • GitLab 17.9에서 기밀 이슈 https://gitlab.com/gitlab-org/gitlab/-/issues/472018에서 일반 공개됨. 기능 플래그 rewrite_history_ui 제거됨.

실수로 커밋된 민감하거나 기밀 정보를 영구적으로 삭제하여 저장소 기록에서 더 이상 액세스할 수 없도록 합니다. 문자열 목록을 ***REMOVED***로 교체합니다.

Warning

이 작업은 되돌릴 수 없습니다. 기록을 재작성하고 하우스키핑을 실행하면 변경 사항은 영구적입니다.

GitLab에서 파일을 수정하면 노출된 비밀 정보가 제거되지만 다음도 수행됩니다:

  • Git 기록을 재작성합니다. 이전 커밋 기록을 기반으로 한 기존 태그와 브랜치가 올바르게 작동하지 않을 수 있습니다.
  • 파괴적입니다. 기존 로컬 클론은 업데이트된 저장소와 호환되지 않으며 재클론해야 합니다.
  • 수정이 콘텐츠를 업데이트하기 때문에 커밋 해시를 업데이트합니다.
  • 재작성 프로세스 중에 커밋 서명을 삭제합니다.
  • 커밋 해시에 의존하는 기능을 중단시키며 다음을 포함합니다:
    • 열린 머지 리퀘스트. 열린 머지 리퀘스트가 머지에 실패하고 수동 리베이스가 필요할 수 있습니다.
    • 이전 커밋에 대한 링크로, 404 오류가 발생합니다.
  • 이전 커밋 SHA를 참조하는 파이프라인이 중단되어 재구성이 필요할 수 있습니다.

저장소 무결성을 위해 대신 다음을 수행해야 합니다:

이 방법은:

  • 향후 비밀 정보 유출을 사전에 방지합니다.
  • 보안 규정 준수를 보장하면서 Git 기록을 유지합니다.

자세한 내용은 시크릿 푸시 보호를 참조하세요.

또는 저장소에서 특정 파일을 완전히 삭제하려면 blob 제거를 참조하세요.

전제 조건:

  • 프로젝트의 Owner 역할이 있어야 합니다.

저장소에서 텍스트를 수정하려면:

  1. 상단 바에서 Search or go to를 선택하고 프로젝트를 찾습니다.
  2. Settings > Repository를 선택합니다.
  3. Repository maintenance를 확장합니다.
  4. Redact text를 선택합니다.
  5. 드로어에서 수정할 텍스트를 입력합니다. 정규 표현식과 글로브 패턴이 허용됩니다.
  6. Redact matching strings를 선택합니다.
  7. 확인 대화 상자에서 프로젝트 경로를 입력합니다.
  8. Yes, redact matching strings를 선택합니다.
  9. 왼쪽 사이드바에서 Settings > General을 선택합니다.
  10. Advanced를 확장합니다.
  11. Run housekeeping을 선택합니다. 작업이 완료될 때까지 최소 30분을 기다립니다.
  12. 동일한 Settings > General > Advanced 섹션에서 Prune unreachable objects를 선택합니다. 이 작업은 완료하는 데 약 5-10분이 걸립니다.
Note

민감한 정보가 포함된 프로젝트가 포크된 경우 하우스키핑 작업이 이 수정 프로세스를 완료하지 못해 포크된 데이터가 포함된 특수 객체 풀 저장소의 무결성을 유지할 수 있습니다 (해당 데이터를 포함하는). 도움이 필요하면 GitLab 지원에 문의하세요.

트러블슈팅#

이 섹션에는 발생할 수 있는 문제에 대한 해결책이 있습니다.

GUI에 표시된 잘못된 저장소 통계#

GitLab 인터페이스에 표시된 저장소 크기나 커밋 수가 내보낸 .tar.gz나 로컬 저장소와 다른 경우:

  1. GitLab 관리자에게 Rails 콘솔을 사용하여 강제 업데이트를 요청합니다.

  2. 관리자는 다음 명령을 실행해야 합니다:

    p = Project.find_by_full_path('<namespace>/<project>')
    p.statistics.refresh!
    
  3. 프로젝트 통계를 지우고 재계산을 트리거하려면:

    p.repository.expire_all_method_caches
    UpdateProjectStatisticsWorker.perform_async(p.id, ["commit_count","repository_size","storage_size","lfs_objects_size","container_registry_size"])
    
  4. 총 아티팩트 스토리지 공간을 확인하려면:

    builds_with_artifacts = p.builds.with_downloadable_artifacts.all
    
    artifact_storage = 0
    builds_with_artifacts.find_each do |build|
      artifact_storage += build.artifacts_size
    end
    
    puts "#{artifact_storage} bytes"
    

정리 후 공간이 확보되지 않음#

저장소 정리 프로세스를 완료했지만 스토리지 사용량이 변경되지 않은 경우:

  • 도달할 수 없는 객체는 2주 유예 기간 동안 저장소에 남아 있습니다.
  • 이러한 객체는 내보내기에 포함되지 않지만 여전히 파일 시스템 공간을 차지합니다.
  • 2주 후에 이러한 객체가 자동으로 정리되어 스토리지 사용량 통계가 업데이트됩니다.
  • 이 프로세스를 가속화하려면 관리자에게 'Prune Unreachable Objects' 하우스키핑 작업을 실행해 달라고 요청합니다.

blob이 제거되지 않음#

blob이 성공적으로 제거되면 GitLab은 프로젝트 감사 로그에 항목을 추가하고 작업을 시작한 사람에게 이메일 알림을 보냅니다.

blob 제거에 실패하면 GitLab은 제목 <project_name> | Project history rewrite failure로 시작자에게 이메일 알림을 보냅니다. 이메일 본문에는 전체 오류 메시지가 포함됩니다.

가능한 오류 및 해결 방법:

  • validating object ID: invalid object ID: 객체 ID 목록에 구문 오류 또는 잘못된 객체 ID가 포함되어 있습니다. 해결하려면:
    1. 객체 ID 목록을 재생성합니다.
    2. blob 제거 단계를 다시 실행합니다.
  • source repository checksum altered: blob 제거 프로세스 중에 누군가가 커밋을 푸시한 경우 발생합니다. 해결하려면:
    1. 저장소에 대한 모든 푸시를 일시적으로 차단합니다.
    2. blob 제거 단계를 다시 실행합니다.
    3. 프로세스가 성공적으로 완료된 후 푸시를 다시 활성화합니다.

저장소 크기 제한 도달#

저장소 크기 제한에 도달한 경우:

  • 일부 데이터를 제거하고 새 커밋을 만들어 보세요.
  • 성공하지 못하면 일부 blob을 Git LFS로 이동하거나 기록에서 오래된 의존성 업데이트를 제거하는 것을 고려합니다.
  • 여전히 변경 사항을 푸시할 수 없으면 GitLab 관리자에게 연락하여 일시적으로 프로젝트의 제한을 늘려 달라고 요청합니다.
  • 최후의 수단으로 새 프로젝트를 만들고 데이터를 마이그레이션합니다.
Note

새 커밋에서 파일을 삭제해도 저장소 크기가 즉시 줄어들지 않습니다. 이전 커밋과 blob이 여전히 존재하기 때문입니다. 크기를 효과적으로 줄이려면 git filter-repo와 같은 도구를 사용하여 기록을 재작성해야 합니다.