Git で大きなファイルを管理し、格納する

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Git は、バージョン間の違いを簡単に見つけ出し、コードを簡単に圧縮できるため、ソース コードの占有領域を小さく保つために便利です。 圧縮が不十分で、バージョン間で全体的に変更される大きなファイル (バイナリなど) は、これらが Git リポジトリに保存されるときに問題が発生します。 Git の高速パフォーマンスは、ローカル ストレージからファイルのすべてのバージョンに対応し、切り替える能力によって実現されています。

リポジトリ内に差分を取得できない大きなファイルがある場合は(バイナリなど)、これらのファイルへの変更をコミットするたびにその完全なコピーをリポジトリ内に保持します。 これらのファイルの多くのバージョンがリポジトリに存在する場合、コードのチェックアウト、ブランチ、フェッチ、複製までの時間が大幅に長くなります。

Git に保存する必要があるファイルの種類

依存関係ではなくコミット ソース コード

チームはエディターとツールを使用してファイルの作成や更新を行うので、チームが Git のワークフローの利点を享受できるように、これらのファイルを Git に配置する必要があります。 他の種類のファイルを自分のリポジトリにコミットしないでください。たとえば、DLL、ライブラリ ファイル、その他の依存関係など、自分のチームが作成したものではないが、自分のコードが依存しているものなどです。 これらのファイルはパッケージ管理を通じてシステムに配信します。

パッケージを展開するときに、パッケージ管理によって依存関係がバンドルされ、システムにファイルがインストールされます。 パッケージはバージョン管理されており、環境に同じパッケージがインストールされている限り、ある環境でテストされたコードは別の環境でも同じように実行できます。

出力をコミットしない

ビルドとテストからバイナリ、ログ、トレース出力、または診断データをコミットしないでください。 これらは、ソース コード自体ではなく、コードからの出力です。 作業項目のトラッキング ツールまたはチーム ファイル共有を通じて、ログとトレース情報をチームと共有します。

更新頻度の低い小さなバイナリ ソースを Git に保存する

更新頻度の低いバイナリ ソース ファイルでは、コミットされたバージョンが比較的少なくなります。 ファイル サイズが小さい場合、多くのスペースを占有しません。 Web 用の画像やアイコンなど、小さなアート アセットもこのカテゴリに入ります。 チームが一貫したワークフローを使用できるように、これらのファイルをソースの残りとともに Git に保存することをお勧めします。

重要

小さなバイナリであっても、頻繁に更新すると問題を引き起こす可能性があります。 たとえば、100 KB バイナリ ファイルにおける 100 回の変更は、1 MB バイナリにおける10 回の変更と同じストレージを使用します。 更新の頻度が高いため、バイナリが小さいほど、大きなバイナリよりも分岐のパフォーマンスが遅くなります。

頻繁に更新される大きなバイナリ アセットをコミットしない

Git は 1 つのメイン バージョンのファイルを管理し、デルティフィケーションと呼ばれるプロセスでそのバージョンとの差分のみを保存します。 Deltification とファイル圧縮により、Git はコード履歴全体をローカル リポジトリに保存できます。 通常、大きなバイナリはバージョン間で完全に変更され、また多くの場合には、既に圧縮されています。 これらのファイルは、バージョン間の違いが大きいため、Git で管理するのが困難です。

Git はファイルの各バージョンの内容全体を保存する必要があるため、deltification と圧縮によって領域を節約することが困難です。 これらのファイルの完全なバージョンを保存すると、リポジトリのサイズが時間の経過とともに増加します。 リポジトリ サイズが大きくなると、分岐のパフォーマンスが低下し、クローン時間が長くなり、ストレージ要件が高くなります。

大きなバイナリ ソース ファイルを操作するための戦略

  • データの圧縮アーカイブをコミットしないでください。 ファイルの圧縮を解除し、差分ソースをコミットすることをお勧めします。 Git でリポジトリ内のデータ圧縮を処理してみましょう。
  • コンパイル済みコードやその他のバイナリ依存関係はコミットしないでください。 ソースをコミットして依存関係を構築するか、パッケージ管理ソリューションを使用してこれらのファイルをバージョン管理し、システムに提供します。
  • 構成とその他の構造化データを、JSON などの差分化できるプレーン テキスト形式で保存します。

Git LFS とは

バージョン間で大きな違いがあり、頻繁に更新されるソース ファイルがある場合は、Git ラージ ファイル ストレージ (LFS) を使用してこれらのファイルの種類を管理できます。 Git LFS は Git の拡張機能であり、リポジトリへのコミット内の大きなファイルを説明するデータを提供します。 これより、バイナリ ファイルの内容が別のリモート ストレージに保存されます。

リポジトリ内のブランチをクローンし、切り替えると、Git LFS によってそのリモート ストレージから正しいバージョンをダウンロードされます。 ローカルの開発ツールは、まるでリポジトリに直接コミットしたかのように、ファイルを透過的に操作します。

メリット

Git LFS の利点は、チームが作成するファイルにかかわらず、使い慣れたエンド ツー エンドの Git ワークフローを使用できることです。 LFS は大きなファイルを処理して、リポジトリ全体への悪影響を回避します。 さらに、バージョン 2.0 時点で Git LFS はファイル ロックをサポートしており、ビデオ、サウンド、ゲーム マップのように大規模で拡散しない資産を扱うために役立ちます。

Git LFS は Azure DevOps Services で完全にサポートされており、無料です。 Visual Studio で LFS を使用するには、Visual Studio 2015 Update 2 以降が必要です。 指示に従ってクライアントをインストールし、ローカル リポジトリ上のファイルに対する LFS の追跡を設定し、変更を Azure Repos にプッシュするだけです。

制限事項

Git LFS には、その使用を採用する前に考慮すべき欠点がいくつかあります。

  • チームが使用するすべての Git クライアントでは、Git LFS クライアントをインストールし、その追跡の構成を理解する必要があります。
  • Git LFS クライアントが正しくインストールされ、構成されていない場合、リポジトリをクローンするときに Git LFS を介してコミットされたバイナリ ファイルが表示されません。 Git は、バイナリ ファイルではなく、大きなファイルを説明するデータをダウンロードします (これが Git LFS によってリポジトリにコミットされるものです)。 Git LFS クライアントがインストールされていない状態で大きなバイナリをコミットすると、バイナリはリポジトリにプッシュされます。
  • たとえ親が共通であっても、2 つの異なるバージョンのバイナリ ファイルの変更を Git によってマージすることはできません。 2 人が同時に同じファイルで作業している場合、相手の作業を上書きしないように、2 人で協力して変更を調整する必要があります。 Git LFS のファイル ロック機能が役立ちます。 ただし、ユーザーは作業を始める前に常にバイナリ資産の最新コピーを取得するように注意する必要があります。
  • 現在、Azure Repos では、Git LFS が追跡するファイルがあるリポジトリでのセキュア シェル (SSH) の使用がサポートされていません。
  • ユーザーがウェブ インターフェイスを介してバイナリ ファイルを Git LFS 用に構成されたリポジトリにドラッグする場合、Git LFS クライアントを介してコミットされるポインターではなく、リポジトリにバイナリがコミットされます。
  • 厳密なファイル サイズ制限はありませんが、サーバーの使用可能な空き領域と現在のワークロードによって、パフォーマンスと機能が制限されることがあります。
  • ひとつのファイルのアップロード時間の上限は 1 時間です。

ファイル形式

Git LFS の追跡ファイルについてリポジトリに書き込まれるファイルには、各行にキーと値のペアを含む数行があります。

version https://git-lfs.github.com/spec/v1
oid a747cfbbef63fc0a3f5ffca332ae486ee7bf77c1d1b9b2de02e261ef97d085fe
size 4923023

Note

バージョン値に含まれる GitHub URL は、LFS ポインター ファイルの種類のみを定義します。 これは、バイナリ ファイルへのリンクではありません。

既知の問題

Azure DevOps Server で LFS のバージョンが 2.4.0 以前のものを使用する場合、Kerberos ではなく NTLM を経由して認証するための追加の設定手順が必要です。 この手順は LFS 2.4.0 から不要になっているため、アップグレードを強くお勧めします。