Git LFS 개발 가이드라인
이 페이지에는 GitLab 팀원을 위한 개발자 중심 정보가 포함되어 있습니다. 사용자 설명서는 Git Large File Storage를 참조하세요.
컨트롤러 및 서비스
Repositories::GitHttpClientController
여기에 정의된 인증 방법은 모든 다른 LFS 컨트롤러에서 상속됩니다.
Repositories::LfsApiController
#batch
인증 후 batch
액션이 Git LFS 클라이언트에 의해 다운로드 및 업로드 (예: 풀, 푸시, 클론) 중에 호출되는 첫 번째 액션입니다.
Repositories::LfsStorageController
#upload_authorize
Workhorse에 payload를 제공하며, 파일을 저장할 Workhorse의 경로를 포함합니다. 원격 객체 리포지터리일 수도 있습니다.
#upload_finalize
이미 Workhorse가 업로드한 파일에 대한 정보를 포함하는 Workhorse로부터의 요청을 처리합니다 (이 middleware 참조),
이로써 gitlab
은 다음을 할 수 있습니다:
-
LfsObject
생성 - 기존의
LfsObject
를LfsObjectsProject
가 있는 프로젝트에 연결
LfsObject 및 LfsObjectsProject
- 특정
oid
(파일의 SHA256 체크섬) 및 파일 크기로 주어진 파일에 대해 하나의LfsObject
만 생성됩니다. -
LfsObjectsProject
는LfsObject
를Project
에 연결합니다. 파일이 프로젝트를 통해 액세스할 수 있는지를 결정합니다. - 이러한 객체들은 또한 특정 프로젝트가 사용 중인 LFS 리포지터리의 양을 계산하는 데 사용됩니다.
자세한 내용은
ProjectStatistics#update_lfs_objects_size
참조.
Repositories::LfsLocksApiController
LFS에 대한 잠금 API를 처리합니다. 주로 해당 서비스로 위임됩니다:
Lfs::LockFileService
Lfs::UnlockFileService
Lfs::LocksFinderService
#verify
- 이 엔드포인트는 클라이언트가 푸시되는 파일 중 다른 사용자에 의해 소유된 잠금을 확인할 수 있게 하는 payload로 응답합니다.
- 클라이언트 측
lfs.locksverify
구성을 설정하여, 다른 사용자에 의해 소유된 잠금이 있으면 클라이언트가 푸시를 중단하도록 할 수 있습니다. - 다른 사용자가 소유한 잠금의 존재는 또한 서버 측에서도 유효성이 검사됩니다.
인증 예시
- 클라이언트는 자격 증명을 몇 가지 다른 방법으로 저장하도록 구성할 수 있습니다. Git LFS 인증에 대한 Git LFS 설명서를 참조하세요.
-
gitlab-shell
에서gitlab-lfs-authenticate
를 실행합니다.gitlab-lfs-authenticate
에 관한 Git LFS 설명서를 참조하세요. -
gitlab-shell
은 GitLab API에 요청을 생성합니다. - 토큰으로 shell에 응답하며, 이것은 후속 요청에 사용됩니다. 인증에 관한 Git LFS 설명서를 참조하세요.
클론의 예시
- Git LFS는 인가 헤더와 함께 파일을 다운로드할 수 있는 능력을 요청합니다.
-
gitlab
는 객체 디렉터리 및 그들을 찾을 위치로 응답합니다. LfsApiController#batch를 참조하세요. - Git LFS는 이전 응답 중
href
에 대해 각 파일에 대한 요청을 생성합니다. 기본 전송 방식을 사용하여 다운로드가 처리되는 방법를 참조하세요. - 원격 객체 리포지터리가 활성화되어 있는 경우,
gitlab
은 원격 URL로 리디렉션합니다. SendFileUpload를 참조하세요.
예시 푸시
- Git LFS는 파일을 업로드할 수 있는 능력을 요청합니다.
-
gitlab
은 객체 디렉터리과 해당 객체를 찾기 위한 업로드로 응답합니다. 참조: LfsApiController#batch. - Git LFS는 이전 응답의
href
에 대해 각 파일에 대한 요청을 수행합니다. 참조: how uploads are handled with the basic transfer mode. -
gitlab
은 파일을 저장하기 위한 경로를 포함한 페이로드로 응답합니다. 이는 원격 객체 리포지터리가 될 수 있습니다. 참조: LfsStorageController#upload_authorize. - Workhorse가 파일을 저장하는 작업을 수행합니다.
- Workhorse는 업로드한 파일에 대한 정보와 함께
gitlab
에 요청을 수행하여LfsObject
를 생성합니다. 참조: LfsStorageController#upload_finalize.
심층적인 탐구
2019년 4월, Francisco Javier López는 GitLab Git LFS 구현에 대한 심층적인 탐구(오로지 GitLab 팀 멤버: https://gitlab.com/gitlab-org/create-stage/-/issues/1
)를 진행하여, 미래에 해당 코드베이스의 이 부분에서 작업할 수 있는 누구든지 도메인에 특화된 지식을 공유했습니다.
YouTube 녹화와 Google 슬라이드, PDF에서 찾을 수 있습니다.
이 심층 탐구는 GitLab 11.10을 기준으로 했으며, 특정 세부 사항은 변경되었을 수 있지만 여전히 좋은 소개 자료로 사용될 것으로 기대됩니다.
프로젝트 아카이브에 LFS blob 포함하기
- GitLab 13.5에 도입되었습니다.
다음 다이어그램은 GitLab이 프로젝트 아카이브에서 LFS 파일을 해결하는 방법을 보여줍니다.
- 사용자가 UI에서 프로젝트 아카이브를 요청합니다.
- Workhorse가 이 요청을 Rails로 전달합니다.
- 사용자가 아카이브를 다운로드할 수 있는 것이 인증되면, Rails는
Gitlab-Workhorse-Send-Data
의 HTTP 헤더와git-archive
로 시작하는 base64로 인코딩된 JSON 페이로드를 제공합니다. 이 페이로드에는 또한 다시 base64로 인코딩된SendArchiveRequest
이진 메시지가 포함됩니다. - Workhorse가
Gitlab-Workhorse-Send-Data
페이로드를 디코딩합니다. 아카이브가 이미 아카이브 캐시에 존재하는 경우, Workhorse는 해당 파일을 전송합니다. 그렇지 않으면, Workhorse는SendArchiveRequest
를 적절한 Gitaly 서버에 전송합니다. - Gitaly 서버는
git archive <ref>
를 호출하여 런타임에 Git 아카이브 생성을 시작합니다.include_lfs_blobs
플래그가 활성화되어 있는 경우, Gitaly은-c filter.lfs.smudge=/path/to/gitaly-lfs-smudge
Git 옵션을 통해 사용자 정의 LFS 스머지 필터를 활성화합니다. -
git
이.gitattributes
파일을 사용하여 가능한 LFS 포인터를 식별하면,git
은gitaly-lfs-smudge
를 호출하고 표준 입력을 통해 LFS 포인터를 제공합니다. Gitaly은 LFS 객체를 조회할 수 있도록GL_PROJECT_PATH
와GL_INTERNAL_CONFIG
를 환경 변수로 제공합니다. - 유효한 LFS 포인터가 디코딩되면,
gitaly-lfs-smudge
은 워크호스에 내부 API 호출을 수행하여 GitLab에서 LFS 객체를 다운로드합니다. - Workhorse는 이 요청을 Rails로 전달합니다. LFS 객체가 존재하고 프로젝트와 관련이 있는 경우, Rails는
Gitlab-Workhorse-Send-Data
HTTP 헤더와send-url
로 시작하는 base64로 인코딩된 페이로드를 통해 LFS 객체가 위치한 경로(로컬 디스크의 경우) 또는 사전에 서명된 URL(객체 리포지터리가 활성화된 경우)를 송부합니다. - Workhorse는 파일을 검색하여
gitaly-lfs-smudge
프로세스에 전송하고, 해당 내용을 표준 출력에 작성합니다. -
git
은 이 출력을 읽어들이고, 그것을 다시 Gitaly 프로세스로 송부합니다. - Gitaly은 데이터를 Rails로 송부합니다.
- 아카이브 데이터가 클라이언트로 송부됩니다.
7단계에서 gitaly-lfs-smudge
필터가 잘못된 LFS 블롭이 저장되지 않도록 하려면, Workhorse에게, Rails가 아닌 해결해야 합니다. 이를 위해 GitLab 13.5에서 기본 옴니버스 구성을 변경하여 Gitaly가 Rails가 아닌 Workhorse와 통신하도록 설정했습니다.
이 변경의 부작용 중 하나는: Gitaly 또는 gitaly-lfs-smudge
에서 수행하는 내부 API 요청의 상관 ID가 원래 요청의 상관 ID가 유지되지 않고 무작위 값으로 유지되는 것이며, 이는 이 Workhorse 이슈가 해결될 때까지 유효합니다.
관련 주제
- 블로그 글: Git LFS 시작하기
- 사용자 설명서: Git Large File Storage (LFS)
- Self-managed 인스턴스용 GitLab Git Large File Storage (LFS) 관리