これは、なにをしたくて書いたもの?
今まで使ってこなかったのですが、GitのPartial CloneとShallow Cloneについて見ておいた方がよさそうだなと思ったので
調べてみることにしました。
GitのPartial CloneとShallow Clone
GitのPartial CloneとShallow Cloneについては、まずはGitHubのブログエントリーを見るのがよさそうです。
Get up to speed with partial clone and shallow clone - The GitHub Blog
パーシャルクローンとシャロークローンを活用しよう - GitHubブログ
またPartial CloneについてはGitのドキュメントにも出てきます。
Git - partial-clone Documentation
課題感としては、リポジトリーに含まれるファイルやコミット履歴が巨大になった時にダウンロードに時間がかかることですね。
これらへ対応する選択肢がPartial CloneとShallow Cloneです。名称とコマンドの対応は以下になります。
- Partial Clone
- Blobless Clone
git clone --filter=blob:none <url>
- Treeless Clone
git clone --filter=tree:0 <url>
- Blobless Clone
- Shallow Clone
git clone --depth=1 <url>git clone --depth=<N> <url>
Partial Clone
Partial CloneにはBlobless CloneとTreeless Cloneの2種類があります。
Partial Cloneの内容を理解するには、BlobとTreeが指す意味を把握しておく必要があります。
Blobはファイルの中身、Treeはディレクトリーです。
Partial Cloneの種類と特徴は以下になります。
| Partial Cloneの種類 | Blob | Tree | Commit |
|---|---|---|---|
| Blobless Clone | なし | すべてダウンロード | すべてダウンロード |
| Treeless Clone | なし | なし | すべてダウンロード |
Blobがないので、いずれのCloneもgit clone時にファイルの中身がないことになります。
欠けている情報はgit checkoutなどを行うとダウンロードされます。つまり、必要になった段階でダウンロードすることに
なります。
通常、開発者が使うのはBlogless Cloneで、Treeless Cloneは自動ビルドなどを高速に行い、そのリポジトリーはすぐに
捨ててしまうような場合に使うものだとされています。
少し試してみましょう。
RESTEasyのリポジトリーで試してみます。
Blobless Clone。
$ git clone --filter=blob:none https://github.com/resteasy/resteasy
パッと見では通常のcloneが行われたように見えます。
Cloning into 'resteasy'... remote: Enumerating objects: 193574, done. remote: Counting objects: 100% (189/189), done. remote: Compressing objects: 100% (127/127), done. remote: Total 193574 (delta 109), reused 63 (delta 41), pack-reused 193385 (from 5) Receiving objects: 100% (193574/193574), 20.50 MiB | 9.69 MiB/s, done. Resolving deltas: 100% (38887/38887), done. remote: Enumerating objects: 4249, done. remote: Counting objects: 100% (3333/3333), done. remote: Compressing objects: 100% (2148/2148), done. remote: Total 4249 (delta 1520), reused 1189 (delta 1185), pack-reused 916 (from 3) Receiving objects: 100% (4249/4249), 5.98 MiB | 10.19 MiB/s, done. Resolving deltas: 100% (1748/1748), done. Updating files: 100% (4298/4298), done.
ディレクトリー内に移動してもファイルはあるので。
$ cd resteasy $ ll -d * -rw-rw-r-- 1 xxxxx xxxxx 56 3月 22 18:21 CODEOWNERS -rw-rw-r-- 1 xxxxx xxxxx 11357 3月 22 18:21 LICENSE -rw-rw-r-- 1 xxxxx xxxxx 4599 3月 22 18:21 README.adoc -rw-rw-r-- 1 xxxxx xxxxx 1421 3月 22 18:21 dco.txt drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 distribution/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 docbook/ -rwxrwxr-x 1 xxxxx xxxxx 10283 3月 22 18:21 mvnw* -rw-rw-r-- 1 xxxxx xxxxx 6733 3月 22 18:21 mvnw.cmd -rw-rw-r-- 1 xxxxx xxxxx 28435 3月 22 18:21 pom.xml drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 profiling-tests/ drwxrwxr-x 11 xxxxx xxxxx 4096 3月 22 18:21 providers/ -rwxrwxr-x 1 xxxxx xxxxx 10089 3月 22 18:21 publish-docs.sh* -rwxrwxr-x 1 xxxxx xxxxx 12433 3月 22 18:21 release.sh* drwxrwxr-x 2 xxxxx xxxxx 4096 3月 22 18:21 resteasy-bom/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-cdi/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-client/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-client-api/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-client-utils/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-core/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-core-spi/ drwxrwxr-x 2 xxxxx xxxxx 4096 3月 22 18:21 resteasy-dependencies-bom/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-jsapi/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-links/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-reactor/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-rxjava2/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-servlet-initializer/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-stats/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-upgrade-guide/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-wadl/ drwxrwxr-x 3 xxxxx xxxxx 4096 3月 22 18:21 resteasy-wadl-undertow-connector/ drwxrwxr-x 4 xxxxx xxxxx 4096 3月 22 18:21 security/ drwxrwxr-x 7 xxxxx xxxxx 4096 3月 22 18:21 server-adapters/ drwxrwxr-x 8 xxxxx xxxxx 4096 3月 22 18:21 testsuite/ drwxrwxr-x 4 xxxxx xxxxx 4096 3月 22 18:21 wildfly/
これはcloneと同時にcheckoutしているからです。
ここに--no-checkoutオプションを追加すると、チェックアウトしなくなります。
$ git clone --filter=blob:none --no-checkout https://github.com/resteasy/resteasy
この場合、.gitディレクトリー以外がなくなります。
$ cd resteasy $ ls -ld * ls: '*' にアクセスできません: そのようなファイルやディレクトリはありません
この状態でもコミット履歴はしっかり見ることができます。
$ git log
ファイルはどうするかというと、git checkoutした時に初めて取得することになります。
$ git checkout HEAD remote: Enumerating objects: 4249, done. remote: Counting objects: 100% (3333/3333), done. remote: Compressing objects: 100% (2148/2148), done. remote: Total 4249 (delta 1520), reused 1189 (delta 1185), pack-reused 916 (from 3) Receiving objects: 100% (4249/4249), 5.98 MiB | 9.25 MiB/s, done. Resolving deltas: 100% (1748/1748), done. Updating files: 100% (4298/4298), done. Your branch is up to date with 'origin/main'.
次はTreeless Cloneを見てみましょう。
$ git clone --filter=tree:0 https://github.com/resteasy/resteasy
Partial Cloneとはちょっと動きが違いますね。
Cloning into 'resteasy'... remote: Enumerating objects: 11986, done. remote: Counting objects: 100% (29/29), done. remote: Compressing objects: 100% (29/29), done. remote: Total 11986 (delta 6), reused 4 (delta 0), pack-reused 11957 (from 5) Receiving objects: 100% (11986/11986), 4.45 MiB | 7.42 MiB/s, done. Resolving deltas: 100% (1880/1880), done. remote: Enumerating objects: 1170, done. remote: Counting objects: 100% (195/195), done. remote: Compressing objects: 100% (189/189), done. remote: Total 1170 (delta 2), reused 8 (delta 0), pack-reused 975 (from 4) Receiving objects: 100% (1170/1170), 194.00 KiB | 9.24 MiB/s, done. Resolving deltas: 100% (9/9), done. remote: Enumerating objects: 4249, done. remote: Counting objects: 100% (3333/3333), done. remote: Compressing objects: 100% (2148/2148), done. remote: Total 4249 (delta 1520), reused 1189 (delta 1185), pack-reused 916 (from 3) Receiving objects: 100% (4249/4249), 5.98 MiB | 10.25 MiB/s, done. Resolving deltas: 100% (1748/1748), done. Updating files: 100% (4298/4298), done.
この後、cloneしたリポジトリー内でgit checkoutなどを行うことができますが、状況によってダウンロードが行われるのは
Partial Cloneと同じです。一方で実行コストはこちらの方が高いようなので、基本的には使わないのでしょう。
Shallow Clone
Shallow Cloneは--depthで指定した範囲外のコミット履歴を切り捨てるものです。
$ git clone --depth=1 https://github.com/resteasy/resteasy
この結果clone速度は高速になりますが、コミット履歴がなくなります。git logなどは挙動が変わります。
$ cd resteasy $ git log | grep commit | wc -l 1
なので、過去の情報を参照するコマンドはうまく動かなくということです。
自動ビルドなどその時の最新のコミットだけが必要で、あとは不要になる場合に使います。
Treeless Cloneと位置づけが重複しているようにも見えますが、コミット履歴が必要な場合はTreeless Cloneを選ぶという
感じでしょう。