今まで使っていなかった Git コマンドを学んでいく.今回は git sparse-checkout
を試す.
git sparse-checkout とは?
コマンド名にある sparse
は「わずかな」という意味で,Git リポジトリの「一部」を取得できる.git clone --depth
を使ってコミットを刈り取るのではなく,指定したディレクトリを取得する.モノリポ(モノレポ)構成のときに効果的に使える.git sparse-checkout
は歴史的な変化もあり,今年になって改善されている.記事を検索すると Git 2.25 より前の git sparse-checkout
を紹介した記事が多いように感じたため,今回は Git 2.26.2 を使って試した.
- Git 1.7
- 2010年2月 リリース
git sparse-checkout
導入
- Git 2.25
- 2020年1月 リリース
git sparse-checkout
機能改善- Highlights from Git 2.25 - The GitHub Blog
- Git 2.26
- 2020年3月 リリース
git sparse-checkout add
追加- Highlights from Git 2.26 - The GitHub Blog
derrickstolee/sparse-checkout-example を使う
git sparse-checkout
を試すために,そこそこ大きめな GitHub リポジトリを探していた.以下の GitHub Blog の記事を読んだところ git sparse-checkout
を試す手順(Git 2.25 前提)と,サンプルリポジトリが載っていたため,今回は derrickstolee/sparse-checkout-example
リポジトリ(モノリポ構成)を使うことにした.
1. 既存リポジトリで git sparse-checkout
を使う
まず,既存リポジトリ(git clone
をした状態)で git sparse-checkout
を使っていく.git clone
をして,ファイル数をカウントすると 1585個
となる.ディレクトリ構成は GitHub Blog に載っている画像を見ればすぐ理解できる.tree
で簡単に紹介すると,以下のようにモノリポ構成(2階層)になっている.例えば client/android
ディレクトリや web/browser
ディレクトリなど.
$ git clone git@github.com:derrickstolee/sparse-checkout-example.git Cloning into 'sparse-checkout-example'... remote: Enumerating objects: 21, done. remote: Counting objects: 100% (21/21), done. remote: Compressing objects: 100% (19/19), done. remote: Total 1901 (delta 2), reused 11 (delta 1), pack-reused 1880 Receiving objects: 100% (1901/1901), 170.93 MiB | 2.56 MiB/s, done. Resolving deltas: 100% (177/177), done. Updating files: 100% (1560/1560), done. $ cd sparse-checkout-example $ find . -type f | wc -l 1585 $ tree -L 2 . ├── LICENSE.md ├── README.md ├── bootstrap.sh ├── client │ ├── README │ ├── android │ ├── electron │ └── iOS ├── service │ ├── README │ ├── common │ ├── identity │ ├── items │ └── list └── web ├── README ├── browser ├── editor └── friends
さっそく,git sparse-checkout init --cone
を実行して sparse-checkout
を有効化する.--cone
オプションはパターンマッチによりディレクトリ探索のパフォーマンスを改善するオプションとして付けておく.直後にファイル数をカウントすると,なんと 30個
に減っている.client/android
ディレクトリや web/browser
ディレクトリも除外されている.設定は .git/info/sparse-checkout
ファイルにあり,意味としては「作業ディレクトリをルートにあるファイルに制限する」となる.
$ git sparse-checkout init --cone $ find . -type f | wc -l 30 $ tree -L 2 . ├── LICENSE.md ├── README.md └── bootstrap.sh $ cat .git/info/sparse-checkout /* !/*/
今のままだと重要なコードも除外されているため,例えば「Android アプリを開発するチーム」の場合は,git sparse-checkout set client/android
を実行して,ディレクトリを設定できる.実際にファイル数は 56個
になり,client/android
ディレクトリを参照できるようになる.
$ git sparse-checkout set client/android $ find . -type f | wc -l 56 $ tree -L 2 . ├── LICENSE.md ├── README.md ├── bootstrap.sh └── client ├── README └── android $ cat .git/info/sparse-checkout /* !/*/ /client/ !/client/*/ /client/android/
次に「フロントエンドを開発するチーム」の場合は,git sparse-checkout set service web/browser
を実行する.すると service
ディレクトリと web/browser
ディレクトリを参照できるようになる.set
は上書きする仕様になっているため,既に client/android
ディレクトリは参照できなくなっている.さらに .git/info/sparse-checkout
ファイルを見なくても git sparse-checkout list
を使えばディレクトリを確認できる.
$ git sparse-checkout set service web/browser $ find . -type f | wc -l 636 $ tree -L 2 . ├── LICENSE.md ├── README.md ├── bootstrap.sh ├── service │ ├── README │ ├── common │ ├── identity │ ├── items │ └── list └── web ├── README └── browser $ git sparse-checkout list service web/browser
なお,Git 2.26 から git sparse-checkout add
も使えるため,ディレクトリを追加するときに毎回 git sparse-checkout set
をし直していた手順をシンプルにできる.次の手順で add
を使っていく.
2. git clone --filter=blob:none --no-checkout
と組み合わせる
git clone
をするときに --filter=blob:none
オプションを付けると,オブジェクトのダウンロードをせずに clone
できる(Partial Clone とも言う).さらに --no-checkout
オプションを付けると,チェックアウトをせずに clone
できる.新しくリポジトリを取得する場合は git clone --filter=blob:none --no-checkout
と組み合わせるとオーバーヘッドを減らして,モノリポを管理できる.
$ git clone --filter=blob:none --no-checkout git@github.com:derrickstolee/sparse-checkout-example.git Cloning into 'sparse-checkout-example'... remote: Enumerating objects: 13, done. remote: Counting objects: 100% (13/13), done. remote: Compressing objects: 100% (12/12), done. remote: Total 373 (delta 1), reused 7 (delta 1), pack-reused 360 Receiving objects: 100% (373/373), 76.78 KiB | 644.00 KiB/s, done. Resolving deltas: 100% (18/18), done. $ cd sparse-checkout-example $ find . -type f | wc -l 29
同じように git sparse-checkout init --cone
を実行して sparse-checkout
を有効化する.今回は add
を使って client/android
ディレクトリと service
ディレクトリと web/browser
ディレクトリを参照できるようにする.git sparse-checkout
の手順は同じだけど,オブジェクトのダウンロードを後回しにできる点はメリットと言える.
$ git sparse-checkout init --cone $ git sparse-checkout add client/android $ git sparse-checkout add service web/browser $ find . -type f | wc -l 667 $ tree -L 2 . ├── LICENSE.md ├── README.md ├── bootstrap.sh ├── client │ ├── README │ └── android ├── service │ ├── README │ ├── common │ ├── identity │ ├── items │ └── list └── web ├── README └── browser
まとめ
今まで使っていなかった Git コマンドとして,今回は git sparse-checkout
を試した.モノリポ(モノレポ)構成のときに効果的に使える.もし新しくリポジトリを取得する場合は git clone --filter=blob:none --no-checkout
と組み合わせるとオーバーヘッドを減らして,素早く clone
できる点も覚えておくと良さそう!