部分クローン
Git リポジトリのサイズが大きくなると、作業が煩雑になることがあります:
- ダウンロードしなければならない大量の履歴。
- 必要なディスク容量が大きい
パーシャルクローンは、「リポジトリの完全なコピーを持たずにGitを機能させる」パフォーマンスの最適化です。この作業の目的は、Gitが非常に大きなリポジトリをよりうまく扱えるようにすることです。”
Git 2.22.0以降が必要です。
ファイルサイズによる絞り込み
GitLab 12.10で導入されました。
Gitに大きなバイナリファイルを保存することは、通常は推奨されません。なぜなら、大きなファイルを追加するたびに、その後に変更をクローンしたりフェッチしたりするすべての人がダウンロードされるからです。これらのダウンロードには時間がかかり、特にインターネット接続が遅かったり信頼できなかったりする場合には問題があります。
ファイルサイズフィルター付きの部分クローンを使うと、厄介な大きなファイルをクローンやフェッチから除外することで、この問題を解決できます。Gitが見つからないファイルを見つけたら、オンデマンドでダウンロードします。
リポジトリをクローンする際には、--filter=blob:limit=<size>
引数を使います。たとえば、1メガバイト以上のファイルを除外してリポジトリをクローンするには、次のようにします:
git clone --filter=blob:limit=1m git@gitlab.com:gitlab-com/www-gitlab-com.git
この場合、次のように出力されます:
Cloning into 'www-gitlab-com'...
remote: Enumerating objects: 832467, done.
remote: Counting objects: 100% (832467/832467), done.
remote: Compressing objects: 100% (207226/207226), done.
remote: Total 832467 (delta 585563), reused 826624 (delta 580099), pack-reused 0
Receiving objects: 100% (832467/832467), 2.34 GiB | 5.05 MiB/s, done.
Resolving deltas: 100% (585563/585563), done.
remote: Enumerating objects: 146, done.
remote: Counting objects: 100% (146/146), done.
remote: Compressing objects: 100% (138/138), done.
remote: Total 146 (delta 8), reused 144 (delta 8), pack-reused 0
Receiving objects: 100% (146/146), 471.45 MiB | 4.60 MiB/s, done.
Resolving deltas: 100% (8/8), done.
Updating files: 100% (13008/13008), done.
Filtering content: 100% (3/3), 131.24 MiB | 4.65 MiB/s, done.
出力が長くなっているのは、Git:
- リポジトリをクローンする際に、1メガバイトを超えるファイルを除外するからです。
- デフォルトブランチをチェックアウトするために必要な、見つからない大きなファイルをダウンロードします。
ブランチを変更すると、Git はさらに足りないファイルをダウンロードするかもしれません。
オブジェクトの種類による絞り込み
GitLab 12.10で導入されました。
何百万ものファイルと長い履歴を持つリポジトリでは、すべてのファイルを除外し、git sparse-checkout
、作業コピーのサイズを小さくすることができます。
# Clone the repo excluding all files
$ git clone --filter=blob:none --sparse git@gitlab.com:gitlab-com/www-gitlab-com.git
Cloning into 'www-gitlab-com'...
remote: Enumerating objects: 678296, done.
remote: Counting objects: 100% (678296/678296), done.
remote: Compressing objects: 100% (165915/165915), done.
remote: Total 678296 (delta 472342), reused 673292 (delta 467476), pack-reused 0
Receiving objects: 100% (678296/678296), 81.06 MiB | 5.74 MiB/s, done.
Resolving deltas: 100% (472342/472342), done.
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (25/25), done.
remote: Total 28 (delta 0), reused 12 (delta 0), pack-reused 0
Receiving objects: 100% (28/28), 140.29 KiB | 341.00 KiB/s, done.
Updating files: 100% (28/28), done.
$ cd www-gitlab-com
$ git sparse-checkout set data --cone
remote: Enumerating objects: 301, done.
remote: Counting objects: 100% (301/301), done.
remote: Compressing objects: 100% (292/292), done.
remote: Total 301 (delta 16), reused 102 (delta 9), pack-reused 0
Receiving objects: 100% (301/301), 1.15 MiB | 608.00 KiB/s, done.
Resolving deltas: 100% (16/16), done.
Updating files: 100% (302/302), done.
詳しくは、sparse-checkout
の Git ドキュメントをご覧ください。
ファイルパスによるフィルタリング
部分クローンとスパースチェックアウトのより深いインテグレーションは、--filter=sparse:oid=<blob-ish>
フィルタ仕様によって可能です。このフィルタリングモードでは、.gitignore
ファイルに似たフォーマットを使用して、クローンやフェッチ時に含めるファイルを指定します。
sparse
フィルタを使った部分クローンはまだ実験的です。クローンやフェッチ時に遅くなり、Gitalyリソースの使用率が大幅に増加する可能性があります。すべてのblobをフィルタリングし、代わりにsparse-checkoutを使用してください。 git-sparse-checkout
は、このタイプの部分クローンの使用を単純化し、その制限を克服するからです。詳しくは、rev-list-options
の Git ドキュメントをご覧ください。
-
フィルター仕様の作成たとえば、モノリシックリポジトリにたくさんのアプリケーションがあり、それぞれがルートの別のサブディレクトリにあるとします。ファイル
shiny-app/.filterspec
を作成します:# Only the paths listed in the file will be downloaded when performing a # partial clone using `--filter=sparse:oid=shiny-app/.gitfilterspec` # Explicitly include filterspec needed to configure sparse checkout with # git config --local core.sparsecheckout true # git show master:snazzy-app/.gitfilterspec >> .git/info/sparse-checkout shiny-app/.gitfilterspec # Shiny App shiny-app/ # Dependencies shimmery-app/ shared-component-a/ shared-component-b/
-
ファイルを作成します。clone コマンドを使った
--filter=sparse:oid
のサポートは、スパースチェックアウトと完全にはインテグレーションされていません。# Clone the filtered set of objects using the filterspec stored on the # server. WARNING: this step may be very slow! git clone --sparse --filter=sparse:oid=master:shiny-app/.gitfilterspec <url> # Optional: observe there are missing objects that we have not fetched git rev-list --all --quiet --objects --missing=print | wc -l
bash
や Zsh などとの Git インテグレーションや、Git ステータス情報を自動的に表示するエディターでは、リポジトリ全体を取得するgit fetch
がよく実行されます。これらのインテグレーションを無効にするか再設定する必要があるかもしれません。
部分クローンのフィルタリングの削除
部分クローンフィルタリングを設定している Git リポジトリは、フィルタリングを解除することができます。フィルタリングを削除するには
-
フィルターによって除外されたものをすべて取得し、リポジトリが完全であることを確認します。
git sparse-checkout
を使用していた場合は、git sparse-checkout disable
を使用して無効にします。詳しくはdisable
ドキュメント を参照してください。その後、定期的に
fetch
を実行し、リポジトリが完全であることを確認してください。特にgit sparse-checkout
を使用していない場合に、フェッチするオブジェクトが不足していないかチェックし、フェッチするには、以下のコマンドを使用できます:# Show missing objects git rev-list --objects --all --missing=print | grep -e '^\?' # Show missing objects without a '?' character before them (needs GNU grep) git rev-list --objects --all --missing=print | grep -oP '^\?\K\w+' # Fetch missing objects git fetch origin $(git rev-list --objects --all --missing=print | grep -oP '^\?\K\w+') # Show number of missing objects git rev-list --objects --all --missing=print | grep -e '^\?' | wc -l
- すべてをリパックします。これは例えば
git repack -a -d
を使って行います。これにより、.git/objects/pack/
に3つのファイルだけが残るはずです:-
pack-<SHA1>.pack
ファイル。 - 対応する
pack-<SHA1>.idx
ファイル。 -
pack-<SHA1>.promisor
ファイル。
-
-
.promisor
ファイルを削除します。上記の手順で、pack-<SHA1>.promisor
ファイルが1つだけ残っているはずです。このファイルは空のはずなので、削除してください。 - 部分クローン設定を削除します。部分的なクローン関連の設定変数をGit設定ファイルから削除します。通常は、以下の設定のみを削除します:
-
remote.origin.promisor
. -
remote.origin.partialclonefilter
.
-