git の sparse-checkout を使ってモノリポでも快適にいこう!

こんにちは。エンジニアリングマネージャーをやっている竹内です。

弊社では現在 Git リポジトリをモノリポで運用しています。

tech.asoview.co.jp

上記記事内に

partial cloneやshallow clone、sparse checkoutなどGitで巨大なリポジトリを扱うための機能なども活かし、快適にMonorepoを扱える環境を構築する必要があります。

とありますので、今回は sparse-checkout について書きたいと思います。

sparse-checkout とは

git-scm.com

sparse-checkout とは、ざっくりいうとローカルに checkout するディレクトリを限定することができる git の機能です。 これにより自分が使うディレクトリのみローカル(working tree)に持ってこれます。

モノリポ内には数十のパッケージ(モジュール)がありますが、使いたいパッケージは限られるケースが多いです。 あるいは、マイクロサービス環境の場合などで複数のパッケージを異なるブランチで checkout したいという場合もあります。 普通に git clone すると全パッケージのDLが始まりディスク使うし clone に時間がかかるし大変です。 そこで 私は git の sparse-checkout を使って必要なパッケージのみを手元にDLしています。

sparse-checkout の始め方

こちらです。(※ git version 2.39.2 前提で記載します)

% git clone --filter=blob:none --no-checkout <git repository url>
% cd <repository_name>
% git sparse-checkout set path/to/directory1 path/to/directory2
% git checkout

ちょっとした説明

git clone のオプション

以下は sparse-checkout 用ではなく普通の clone のオプションです。ローカルディスクや clone する時間を削減することを目的としています。

  • --filter=blob:none: clone したときにファイルの中身(blob)を DL させないようになります(ファイルが必要になった時にDLするようです)。これにより .git ディレクトリの中身が小さくなります。
  • --no-checkout: clone したときに checkout しなくなります。これにより clone で .git ディレクトリのみ作成されることになります。

参考までに以下が手元の環境での違いです。かなり違いますね!

コマンド ディスク使用量(.git) ディスク使用量(working tree) 所要時間
git clone 2.6GB 3.2GB 約8分
git clone --filter=blob:none --no-checkout 231MB 0MB 約30秒

ちなみに、以下の記事によると、

github.blog

上記の filter 指定を使う方法をパーシャルクローン(ブロブレスクローン) と呼ぶようです。他にもいくつか種類があるようですが開発作業には向かないようなので、用途に合わせて選択したいですね。

sparse-checkout

set

sparse-checkout を有効にするために set を行う必要があります。(init でも可能ですが、git 2.35.0 で Deprecated になっており将来バージョンで削除されるようです)

set の後続に checkout したいディレクトリを指定します。 そうすると指定されたディレクトリと top-level ディレクトリのファイルが checkout されるようになります。

ちなみに、以下のようにディレクトリを指定しないで実行すると、

git sparse-checkout set

sparse-checkout が有効になり top-level ディレクトリのファイルが checkout されるようになります。

add

add でディレクトリを指定することも可能です。 set はそれまでに設定されているディレクトリを上書きしますが、add なら追加できます。

つまり以下2つは同じ結果となります。

git sparse-checkout set path/to/directory1 path/to/directory2
git sparse-checkout set
git sparse-checkout add path/to/directory1 path/to/directory2

list

list で現在設定されているディレクトリを確認できます。

git sparse-checkout list

どうやらこのコマンドでは set や add で指定したディレクトリのみリストされるようです。 .git/info/sparse-checkout ファイルには以下のような記載があり、これにより top-level ディレクトリのファイルが sparse-checkout の対象になっているようです。(.git/info/sparse-checkout は sparse-checkout を有効にすると作成されるようです)

/*
!/*/

checkout

checkout すると sparse-checkout で指定したディレクトリのみ checkout されます。checkout したあとに add や set を行うとその時点で working tree も更新されます。

git clone の --sparse オプション

git clone に --sparse オプションがあります。これをつけると sparse-checkout が有効になり top-level ディレクトリのファイルのみ checkout されます。つまり git clonegit sparse-checkout set を1つのコマンドで行っているようなものです。

なので、以下のようなコマンドでも sparse-checkout を始めることができます。

% git clone --filter=blob:none --sparse <git repository url>
% cd <repository_name>
% git sparse-checkout add path/to/directory1 path/to/directory2

まとめ

sparse-checkout (とパーシャルクローン)を使うと

  • 必要なパッケージのみ DL できる
  • ディスクも節約できる
  • clone, checkout の時間も節約できる

といったメリットがあります。これで複数のパッケージを clone してもストレスが減るのではないでしょうか! sparse-checkout で快適なモノリポライフを!

PR

アソビューでは一緒に働くメンバーを大募集しています! カジュアル面談もありますので、少しでも興味があればお気軽にご応募いただければと思います!

www.asoview.com

参考資料