DUICUO

Git シリーズ (パート 7): Git による大きなバイナリオブジェクトの管理

[[179200]]

このシリーズの最初の6つの記事では、Gitを使ってテキストファイルのバージョン管理を行う方法を学びました。では、バイナリファイルはどうでしょうか?バイナリファイルもバージョン管理できるのでしょうか?答えはイエスです。Gitには、マルチメディアファイルのような大きなバイナリオブジェクトブロック(BLOB)を扱える拡張機能があります。そこで今回は、Gitを使っていわゆるバイナリアセットを管理する方法を学びましょう。

Git が大きなバイナリオブジェクトファイルをうまく処理できないことは、広く認められている事実のようです。大きなバイナリオブジェクトファイルは大きなテキストファイルとは異なることを覚えておくことが重要です。Git は大きなテキストファイルのバージョン管理には問題なく機能しますが、不透明なバイナリファイルにはうまく対応できず、コミットすべき巨大なブラックボックスとして扱われてしまいます。

こんなシナリオを想像してみてください。あなたはエキサイティングな一人称視点のパズルゲームを制作しており、複雑な3Dモデルを構築しています。ソースファイルはバイナリ形式で保存されており、結果として1GBのファイルになります。一度コミットすると、Gitリポジトリの履歴に1GBのコミットが作成されます。次に、キャラクターの髪型を変更して再度コミットしますが、Gitは髪型と頭部、そしてモデルの残りの部分を分離できないため、さらに1GBのコミットが発生します。次に、目の色を変更してその部分もコミットします。これもまた1GBのコミットです。モデルへの小さな変更が3GBのコミットにまで及ぶ可能性があります。これは、すべてのアセットをバージョン管理しようとしているゲームにとって深刻な問題です。

他のファイル形式とは異なり、.obj のようなテキストファイルは、すべての更新と変更を単一のコミットに保存しますが、実際にはモデルを記述する単純なテキスト行の羅列です。モデルを変更して .obj ファイルに保存し直すと、Git は両方のファイルを行ごとに読み取り、差分を作成して、比較的小さなコミットを作成します。モデルが詳細であればあるほど、コミットは小さくなります。これは Git の標準的な使用例です。ファイル自体は大きいですが、Git は上書きまたはスパースストレージを使用して、データ使用状況の現在の状態に関する完全な記述を構築します。

ただし、すべてがプレーンテキストではなく、Git が必要なため、解決策が必要であり、すでにいくつかの解決策が登場しています。

OSTreeは、オペレーティングシステムのバイナリを管理するために設計されたGNOMEプロジェクトから生まれました。ここでは関係がないので、省略します。

Git Large File Storage (LFS) は、git-media プロジェクトからフォークされた GitHub 上のオープンソース プロジェクトです。git-media と git-annex は、大容量ファイルを管理するための Git 拡張機能です。これらは同じ問題に対する異なるソリューションであり、それぞれに独自の利点があります。どちらも公式プロジェクトではありませんが、私見ではそれぞれ独自の強みを持っています。

  • git-media は、公開アセット用のリポジトリを備えた集中型モデルを採用しています。git-media に、大容量ファイルの保存場所(ハードドライブ、サーバー、クラウドストレージサーバーなど)を指定すると、プロジェクト内のすべてのユーザーがその場所を大容量ファイルの中央プライマリストレージとして扱うようになります。
  • git-annexは分散モデルに重点を置いています。ユーザーは独自のリポジトリを作成し、それぞれにローカルディレクトリ`.git/annex`を配置して大きなファイルを保存できます。これらのアネックス(別ディレクトリ)は定期的に同期され、すべてのユーザーは必要なときにいつでもすべてのリソースにアクセスできます。`annex-cost`で明示的に設定しない限り、git-annexは外部ストレージよりもローカルストレージを優先します。

私はこれらを実現するために git-media と git-annex を本番環境で使用してきたので、その仕組みを以下に概説します。

gitメディア

git-mediaはRubyで開発されているため、まずgemをインストールする必要があります(LCTT翻訳者注:GemはRubyベースの開発ツールキットのセットです)。インストール手順はウェブサイトで確認できます。git-mediaはクロスプラットフォームツールであり、様々なプラットフォームで動作するため、すべてのユーザーはgemをインストールする必要があります。

git-media をインストールしたら、Git のオプションをいくつか設定する必要があります。これはマシンごとに 1 回だけ実行する必要があります。

  1. $ git config filter.media.clean "git-media filter-clean"  
  2. $ git config filter.media.smudge "git-media filter-smudge"  

git-media を使用する各リポジトリで、作成したフィルターを「メディア」として分類したいファイルタイプに組み込む属性を設定します。「メディア」という用語に惑わされないでください。「アセット」という用語の方が適切です。「メディア」は一般的にオーディオ、ビデオ、写真を指しますが、3Dモデル、ベイク処理、テクスチャなども簡単にメディアとして分類できます。

例えば:

  1. $ echo "*.mp4 フィルター=メディア -crlf" >> .gitattributes
  2. $ echo "*.mkv フィルター=メディア -crlf" >> .gitattributes
  3. $ echo "*.wav フィルター=メディア -crlf" >> .gitattributes
  4. $ echo "*.flac フィルター=メディア -crlf" >> .gitattributes
  5. $ echo "*.kra フィルター=メディア -crlf" >> .gitattributes

これらのタイプのファイルをステージングすると、ファイルは .git/media ディレクトリにコピーされます。

サーバー上に既にGitリポジトリがある場合、まずはリポジトリに「母船」の場所、つまりメディアファイルが全ユーザーにプッシュされて共有される際に保存される場所を指定します。これはリポジトリの`.git/config`ファイルで設定されています。ユーザー名、ホスト名、パスを以下の例のように置き換えてください。

  1. [gitメディア]
  2. トランスポート = SCP
  3. autodownload = false # デフォルトはtrue、リソースをロードします
  4. scpuser = セス
  5. scphost = example.com
  6. scppath = /opt/jupiter.git

サーバーの SSH 設定が複雑 (非標準ポートの使用やデフォルト以外の SSH キー ファイル パスの使用など) な場合は、.ssh/config を使用してホストのデフォルト構成を設定してください。

git-media の使い方は通常のファイルと同じです。通常のファイルと BLOB ファイルを同じように扱い、それに応じてコミット操作を実行できます。ワークフローにおける唯一の違いは、特定のタイミングでアセット(またはメディア)を共有リポジトリに同期する必要があることです。

チームのアセットを公開したり、独自のデータをバックアップしたりする必要がある場合は、次のコマンドを使用してください。

  1. $ git メディア同期

git-media 内のファイルを修正版(例えば、強化されたオーディオファイル、完成したマスキングペイント、カラーグレーディングされたビデオファイルなど)に置き換えるには、Git にメディアの更新を明示的に指示する必要があります。これにより、git-media のデフォルト設定(リモートに既に存在するファイルはコピーしない)が上書きされます。

  1. $ git update -インデックス  --本当にリフレッシュ 

チームの他のメンバー(または別のマシンにいるあなた自身)がこのリポジトリをクローンした場合、`.git/config` で `autodownload` オプションが `true` に設定されていない限り、リソースはデフォルトでダウンロードされません。しかし、git-media の `git media sync` コマンドを使えば、これらの問題はすべて解決できます。

git-annex

git-annex は動作が若干異なり、デフォルトでローカルリポジトリを使用しますが、基本的な原理は同じです。git-annex は、ディストリビューションのソフトウェアリポジトリからインストールするか、必要に応じてウェブサイトからダウンロードできます。git-media と同様に、git-annex を使用するには、必ず自分のマシンにインストールしておく必要があります。

初期設定はgit-mediaよりも簡単です。以下のコマンドを実行し、「git-media」をパスに置き換えてサーバー上にrawリポジトリを作成してください。

  1. $ git init --bare --shared /opt/jupiter.git  

次に、それをローカル コンピューターにクローンし、git-annex の初期パスとしてマークします。

  1. $ git clone [email protected]:/opt/jupiter.clone
  2. クローン  「jupiter.clone」 ...
  3. 警告:空のリポジトリをクローンしたようです。
  4. 接続を確認しています...完了しました。
  5. $ git annex init "seth ワークステーション"   
  6. init seth ワークステーション OK

メディアリソースと大容量ファイルを区別するためにフィルターを使用しないでください。大容量ファイルの分類を設定するには、`git annex` コマンドを使用します。

  1. $ git annexbigblobfile.flacを追加
  2. bigblobfile.flacを追加
  3. (チェックサム)OK
  4. (Git状態を記録しています...)

通常のファイルと同じようにファイルを送信します。

  1. $ git commit -m 'サウンドエフェクト用のflacソースを追加しました'  

ただし、git annex はアセットの追跡に独自のブランチを使用するため、プッシュは異なります。リポジトリの管理方法によっては、プッシュに -u オプションが必要になる場合があります。

  1. $ git push -u origin マスター git-annex
  2. [email protected]:/opt/jupiter.git
  3. * [新しいブランチ] master -> master
  4. * [新しいブランチ] git-annex -> git-annex

git-mediaと同様に、通常のgit pushコマンドはサーバーにデータをコピーせず、関連するメッセージのみを送信します。実際にファイルを共有するには、同期コマンドを実行する必要があります。

  1. $ git annex 同期--content  

他のユーザーがすでに共有リソースをコミットしていて、それをプルする必要がある場合は、`git annex sync` コマンドを実行すると、ローカル マシンにはないがサーバー上に存在するリソースをチェックアウトするように求められます。

git-media と git-annex はどちらも非常に柔軟性が高く、サーバーの代わりにローカル リポジトリを使用できるため、プライベートなローカル プロジェクトの管理によく使用されます。

Gitは非常に強力で拡張性の高いシステムアプリケーションソフトウェアなので、ためらうことなく使いこなせるはずです。今すぐ試してみてください!