部分的にgit cloneしたりgit checkoutする
概要
調べ物をしているとフレームワークやライブラリのソースコードが手元に欲しくなるときがあります。
そんなときにリポジトリを丸ごとcloneしたりcheckoutするのではなく、特定の部分に絞ることで時間とディスクを節約したいというのが本記事の趣旨です。
部分的にcloneする
git cloneやgit fetchは--depthオプションで取得するコミット数を指定できます。
Springで試してみましょう。
まず--depthを設定せずに取得します。[1]
$ time git clone --no-checkout git@github.com:spring-projects/spring-framework.git
Cloning into 'spring-framework'...
remote: Enumerating objects: 609218, done.
remote: Counting objects: 100% (38/38), done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 609218 (delta 7), reused 21 (delta 4), pack-reused 609180
Receiving objects: 100% (609218/609218), 163.78 MiB | 6.27 MiB/s, done.
Resolving deltas: 100% (297615/297615), done.
git clone --no-checkout git@github.com:spring-projects/spring-framework.git 13.09s user 2.49s system 49% cpu 31.448 total
$ du -sh spring-framework/.git
193M spring-framework/.git
$
git cloneに31秒かかり、.gitのサイズは193MBでした。
次に--depth=1を設定して取得します。
$ time git clone --no-checkout --depth=1 git@github.com:spring-projects/spring-framework.git
Cloning into 'spring-framework'...
remote: Enumerating objects: 10774, done.
remote: Counting objects: 100% (10774/10774), done.
remote: Compressing objects: 100% (7299/7299), done.
remote: Total 10774 (delta 3038), reused 8527 (delta 2780), pack-reused 0
Receiving objects: 100% (10774/10774), 12.45 MiB | 5.86 MiB/s, done.
Resolving deltas: 100% (3038/3038), done.
git clone --no-checkout --depth=1 0.70s user 0.19s system 14% cpu 6.121 total
$ du -sh spring-framework/.git
13M spring-framework/.git
$
git cloneは6秒になり、.gitのサイズは13MBになりました。
すべてのコミットを取得したくなった場合はgit fetch --unshallowを実行してください。
部分的にcheckoutする
前セクションでgit cloneするときに--no-checkoutというオプションを設定していました。
これを付けているとclone後にHEADをcheckoutしなくなる、つまり.gitディレクトリのみが作成されることになります。
この状態から特定のディレクトリだけをcheckoutするためにgit sparse-checkoutを使います。
--depth=1を設定してcloneしたSpringのリポジトリを使って試してみます。
$ cd spring-framework
$ ls -a
. .. .git
$ git sparse-checkout init
$ git checkout
Your branch is up to date with 'origin/main'.
$ ls -a
. .git .mailmap LICENSE.txt build.gradle gradlew.bat settings.gradle
.. .gitattributes CODE_OF_CONDUCT.adoc README.md gradle.properties import-into-eclipse.md
.editorconfig .gitignore CONTRIBUTING.md SECURITY.md gradlew import-into-idea.md
$
まずls -aで.gitしかないことを確認しています。
次にgit sparse-checkout initでsparse-checkoutを有効化しています。
最後にもう一度ls -aでリポジトリのルートディレクトリにあるファイルだけがcheckoutされていることを確認しています。
sparse-checkoutの設定
sparse-checkoutでどのファイルがcheckoutの対象になるのかはlistサブコマンドで確認できます。
デフォルトの設定は次のようになっています。
$ git sparse-checkout list
/*
!/*/
$
これはルートディレクトリ内のすべてのファイルを対象とし(/*)、ルートディレクトリの1つ下のディレクトリ内は対象外とします(!/*/)。
checkoutの対象を増やしたいときはaddサブコマンドを使います。
試しにspring-webmvcディレクトリを対象に加えましょう。
$ git sparse-checkout list
/*
!/*/
$ ls
CODE_OF_CONDUCT.adoc LICENSE.txt SECURITY.md gradle.properties gradlew.bat import-into-idea.md
CONTRIBUTING.md README.md build.gradle gradlew import-into-eclipse.md settings.gradle
$ git sparse-checkout add spring-webmvc
$ git sparse-checkout list
/*
!/*/
spring-webmvc
$ ls
CODE_OF_CONDUCT.adoc LICENSE.txt SECURITY.md gradle.properties gradlew.bat import-into-idea.md spring-webmvc
CONTRIBUTING.md README.md build.gradle gradlew import-into-eclipse.md settings.gradle
$
sparse-checkoutの設定とファイル一覧を確認してからaddサブコマンドでspring-webmvcを追加しました。
それから再度sparse-checkoutの設定とファイル一覧を確認しています。
spring-webmvcディレクトリがcheckoutできていることがわかります。
sparse-checkoutをやめたい、つまりすべてのファイルをcheckoutしたくなった場合はdisableサブコマンドを使用してください。
-
git cloneの時間を計測するためにtimeコマンドを使用しています。作業環境はmacOSです。 ↩︎
Discussion