部分的に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