💡

一部のディレクトリだけgit cloneする(sparse-checkout)

2021/12/27に公開
$ git clone --filter=blob:none --sparse ${REMOTE_URL}
$ git sparse-checkout set ${DIRECTORY_NAME}

注意事項

2021年12月現在(git version 2.34.1)
git sparse-checkout --helpTHIS COMMAND IS EXPERIMENTAL.とあるように、
git sparse-checkout は変更の可能性があります。お気をつけください。

用途

GitHub などリモートに置かれたレポジトリを手元に clone する際、一部のディレクトリのみを clone します。

レポジトリが育ってくるにつれ、レポジトリのデータ量が大きくなってしまうことがあります。
実際に必要なディレクトリは一部であるにも関わらず、レポジトリ全てのデータを clone するのは好ましくありません。

複数人で開発をしていて、自身の触る箇所が限定されている場合などで有用です。

Sparse Checkout

Git の sparse-checkout という機能を使用しています。
これは、2020年にリリースされた v2.25 でとても使いやすくなった機能です。

sparse - まばらな、少ない
の意味通り、Git レポジトリの一部のみ使用したい場合に使用できます。

sparse-checkout には以下のサブコマンドが提供されています。
init|list|set|add|reapply|disable

使い勝手の良い3つから先に紹介します。

list

sparse-checkout の対象ディレクトリ(操作したいディレクトリ)の一覧を表示します。

$ git sparse-checkout list
mammals
birds/eagle
birds/penguin

set

sparse-checkout の対象ディレクトリを登録します。
set で指定されたディレクトリで list を上書きします。

$ git sparse-checkout list   # 元々3つのディレクトリを登録していた
mammals
birds/eagle
birds/penguin
$ git sparse-checkout set amphibians birds/penguin
$ git sparse-checkout list   # 元々の list に関わらず、新たに登録しなおされる
amphibians
birds/penguin

add

sparse-checkout の対象ディレクトリに追加登録します。

$ git sparse-checkout list   # 元々2つのディレクトリを登録していた
amphibians
birds/penguin
$ git sparse-checkout add mammals/whale
$ git sparse-checkout list   # 元々の list は引き継がれる
amphibians
birds/penguin
mammals/whale

冒頭では clone 時に sparse-checkout を適用する例を挙げていますが、必ずしもそうである必要はありません。
今まで全て管理していたが、レポジトリの肥大化に伴って管理範囲を縮小したい、という場合もあると思います。
さて、残り3つのサブコマンドを紹介します。

init

既存のGitレポジトリに、新たに sparse-checkout を適用できます。
init した際の初期 list は以下のように、ルートディレクトリ直下のファイルのみの登録になっています。

/*
!/*/

disable

sparse-checkoutの適用を無効にします。

$ git sparse-checkout disable

reapply

一度 disable した sparse-checkout を再度適用します。

$ git sparse-checkout reapply

(ユースケース)一部のディレクトリだけ git clone する

git cloneと同時に、sparse-checkout を適用したい場合、
git cloneのオプションとして--spaseが存在します。
sparse-checkout initと同様、ルートディレクトリ直下のファイルのみの登録がなされます。

必要なディレクトリが他にある場合は、sparse-checkout setsparse-checkout addを使用し、作業したいディレクトリを登録します。

$ git clone --filter=blob:none --sparse ${REMOTE_URL}
$ git sparse-checkout set ${DIRECTORY_NAME}

これは記事冒頭のコマンドと同一です。

参考

https://git-scm.com/docs/partial-clone
https://github.blog/2020-01-13-highlights-from-git-2-25/
https://kakakakakku.hatenablog.com/entry/2020/06/04/104940
https://stackoverflow.com/questions/600079/how-do-i-clone-a-subdirectory-only-of-a-git-repository
https://www.infoq.com/jp/news/2020/03/git-2-25-sparse-checkout/

Discussion