Git LFS開発ガイドライン
このPagesには、GitLabチームメンバーのための開発者中心の情報が含まれています。ユーザー向けのドキュメントはGit Large File Storage をご覧ください。
コントローラーとサービス
リポジトリ::GitHttpClientController
ここで定義した認証用のメソッドは、他のすべての LFS コントローラに継承されます。
リポジトリ::LfsApiController
#batch
認証後のbatch
アクションは、Git LFS クライアントがダウンロードやアップロード (pull や push、clone など) を行う際に最初にコールするアクションです。
リポジトリ::LfsStorageController
#upload_authorize
Workhorse にファイルを保存するパスを含むペイロードを提供します。リモートオブジェクトストレージの可能性もあります。
#upload_finalize
Workhorseがすでにアップロードしたファイル(このミドルウェアを参照)の情報を含むWorkhorseからのリクエストを処理し、gitlab
:
-
LfsObject
を作成します。 - 既存の
LfsObject
をLfsObjectsProject
でプロジェクトに接続。
LfsObject と LfsObjectsProject
-
oid
(ファイルのSHA256チェックサム)とファイルサイズが指定されたファイルに対して、LfsObject
が1つだけ作成されます。 -
LfsObjectsProject
LfsObject
s とProject
s を関連付けます。これらは、プロジェクトを通じてファイルにアクセスできるかどうかを決定します。 - これらのオブジェクトは、プロジェクトが使用している LFS ストレージの量を計算するためにも使用されます。詳細については、
ProjectStatistics#update_lfs_objects_size
を参照してください。
リポジトリ::LfsLocksApiController
LFS のロック API を処理します。主に対応するサービスに委譲します:
Lfs::LockFileService
Lfs::UnlockFileService
Lfs::LocksFinderService
これらのサービスはLfsFileLock
を作成および削除します。
#verify
- このエンドポイントはペイロードで応答し、プッシュされているファイルに他のユーザーのロックがあるかどうかをクライアントがチェックできるようにします。
- クライアントサイドの
lfs.locksverify
設定は、他のユーザーに属するロックが存在する場合、クライアントがプッシュを中止するように設定することができます。 - 他のユーザーに属するロックの存在は、サーバー側でも検証されます。
認証の例
- クライアントは、いくつかの方法で認証情報を保存するように設定することができます。認証については Git LFS のドキュメント を参照ください。
-
gitlab-shell
でgitlab-lfs-authenticate
を実行します。gitlab-lfs-authenticate
](https://github.com/git-lfs/git-lfs/blob/bea0287cdd3acbc0aa9cdf67ae09b6843d3ffcf0/docs/api/server-discovery.md#ssh)に関する[Git LFS のドキュメントを参照ください。 -
gitlab-shell
GitLab API へのリクエストを行います。 - その後のリクエストで使用されるトークンでShellに応答します。認証に関する Git LFS ドキュメント を参照。
クローンの例
- Git LFS は、authorization ヘッダを持つファイルをダウンロードする機能を作成者に要求します。
-
gitlab
はオブジェクトの一覧とその場所を応答します。LfsApiController#batch を参照ください。 - Git LFS は、前のレスポンスにある
href
の各ファイルに対してリクエストを行います。基本転送モードでのダウンロードの処理方法を参照。 -
gitlab
リモートオブジェクトストレージが有効になっている場合は、リモートの URL にリダイレクトします。SendFileUpload を参照ください。
プッシュの例
- Git LFS は、ファイルをアップロードする機能を要求します。
-
gitlab
は、オブジェクトのリストとアップロード先を指定して応答します。LfsApiController#batch を参照ください。 - Git LFS は、前のレスポンスで
href
の各ファイルに対してリクエストを行います。基本転送モードでのアップロードの処理方法を参照ください。 -
gitlab
は、Workhorse がファイルを保存するパスを含むペイロードで応答します。リモートオブジェクトストレージの可能性があります。LfsStorageController#upload_authorize を参照してください。 - Workhorse はファイルの保存を行います。
- Workhorse は
gitlab
アップロードされたファイルのgitlab
情報をリクエストし、LfsObject
を作成します。LfsStorageController#upload_finalizeを参照してください。
ディープダイブ
2019年4月、Francisco Javier LópezがGitLabのGit LFS実装に関するDeep Dive(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はHTTPヘッダ
Gitlab-Workhorse-Send-Data
、base64エンコードされたJSONペイロードを先頭にgit-archive
。このペイロードにはSendArchiveRequest
のバイナリメッセージが含まれ、再びbase64でエンコードされます。 - 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は、GL_PROJECT_PATH
とGL_INTERNAL_CONFIG
を環境変数として提供し、LFSオブジェクトの検索を可能にします。 - 有効なLFSポインタがデコードされた場合、
gitaly-lfs-smudge
、Workhorseに内部APIコールを行い、GitLabからLFSオブジェクトをダウンロードします。 - Workhorse はこのリクエストを Rails に転送します。LFS オブジェクトが存在し、プロジェクトに関連付けられている場合、Rails は
ArchivePath
に LFS オブジェクトが存在するパス (ローカルディスクの場合) または署名済みの URL (オブジェクトストレージが有効な場合) を、Gitlab-Workhorse-Send-Data
HTTP ヘッダーのペイロードの先頭にsend-url
を付けて送信します。 - Workhorseはそのファイルを取得し、
gitaly-lfs-smudge
プロセスに送信します。 プロセスはその内容を標準出力に書き込みます。 -
git
はこの出力を読み取り、Gitalyプロセスに送り返します。 - GitalyはデータをRailsに送り返します。
- アーカイブデータはクライアントに送り返されます。
ステップ 7 では、gitaly-lfs-smudge
フィルタは Rails ではなく Workhorse と話をする必要があります。そうしないと、無効な LFS blob が保存されます。これをサポートするために、GitLab 13.5ではOmnibusのデフォルト設定を変更し、GitalyがRailsではなくWorkhorseと話すようにしました。
この変更の副作用として、Gitaly (またはgitaly-lfs-smudge
) による内部 API リクエスト (ステップ 8 で行ったようなもの) では、元のリクエストの相関 ID が保持されません。これらのAPIリクエストの相関IDは、このWorkhorseのイシューが解決されるまでランダムな値になります。
関連するトピック
- ブログ記事Git LFSをはじめよう
- ユーザードキュメントGit ラージファイルストレージ(LFS)
- GitLab Git Large File Storage(LFS)セルフマネージドインスタンス用アドミニストレーション