git clone が遅い時の対策をメモしておく

`git clone` に時間が掛かる、ということがあったので対策を自分用にメモ。
自分用メモなので記事参照多。

# --depth オプションを使う

とりあえず最新の履歴だけ使いたい場合、`--depth` オプションを使って shallow clone を行う。

[git リポジトリの最新の履歴だけを取得する shallow clone](https://qiita.com/usamik26/items/7bfa61b31344206077fb)

同じ環境で比較してみる。

以下は `--depth 1`を指定した場合。

```
# 4秒ほどで完了
$ date;git clone --depth 1 https://github.com/git/git;date;
Sat Jan 29 20:46:31 UTC 2022
Cloning into 'git'...
remote: Enumerating objects: 4172, done.
remote: Counting objects: 100% (4172/4172), done.
remote: Compressing objects: 100% (3682/3682), done.
remote: Total 4172 (delta 385), reused 1888 (delta 320), pack-reused 0
Receiving objects: 100% (4172/4172), 10.18 MiB | 7.63 MiB/s, done.
Resolving deltas: 100% (385/385), done.
Sat Jan 29 20:46:35 UTC 2022

# git log は最新のみ
$ cd git
$ git log
commit 5d01301f2b865aa8dba1654d3f447ce9d21db0b5 (grafted, HEAD -> master, origin/master, origin/HEAD)
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jan 28 16:58:04 2022 -0800

    Sync with Git 2.35.1
```

今度は `--depth` を指定しない場合。

```
# 45秒ほど掛かっている
$date;git clone https://github.com/git/git;date;
Sat Jan 29 20:49:56 UTC 2022
Cloning into 'git'...
remote: Enumerating objects: 321357, done.
remote: Counting objects: 100% (615/615), done.
remote: Compressing objects: 100% (304/304), done.
remote: Total 321357 (delta 364), reused 499 (delta 309), pack-reused 320742
Receiving objects: 100% (321357/321357), 182.31 MiB | 14.14 MiB/s, done.
Resolving deltas: 100% (239979/239979), done.
Sat Jan 29 20:50:41 UTC 2022

# ログは過去のものもある
$cd git
$git log
commit 5d01301f2b865aa8dba1654d3f447ce9d21db0b5 (HEAD -> master, origin/master, origin/main, origin/HEAD)
Merge: 90fb70e458 4c53a8c20f
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jan 28 16:58:04 2022 -0800

    Sync with Git 2.35.1

commit 90fb70e4588bf297caa3fea7b19a0b6c57366f37
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jan 28 16:57:10 2022 -0800

    Name the next one 2.36 to prepare for 2.35.1

    Signed-off-by: Junio C Hamano <gitster@pobox.com>

commit 4c53a8c20f8984adb226293a3ffd7b88c3f4ac1a (tag: v2.35.1, origin/maint)
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jan 28 16:48:42 2022 -0800

    Git 2.35.1

    Signed-off-by: Junio C Hamano <gitster@pobox.com>
```

`Receiving objects: 100% (321357/321357)` となっており、比較するとかなり多い。

# メンテナンスする

[10.7 Gitの内側 - メンテナンスとデータリカバリ](https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-%E3%83%A1%E3%83%B3%E3%83%86%E3%83%8A%E3%83%B3%E3%82%B9%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AA%E3%82%AB%E3%83%90%E3%83%AA?utm_source=pocket_mylist)

> しかし、もし誰かがある時点でプロジェクトの歴史に非常に大きなファイルを1つ加えると、以降のクローンではすべて、その大きなファイルのダウンロードを強いられることになります。これは、直後のコミットでそのファイルをプロジェクトから削除したとしても変わりません。 なぜなら、そのファイルは履歴から到達可能であり、常にそこに存在し続けるためです。

という記載がある。
その為、例えば一度大きなファイルを `git commit` や `git push` した場合、不要になって `git rm` してもダウンロードが必要になってしまう、ということだという理解。

以下の記事もあり。

[Gitリポジトリをメンテナンスして軽量化する](https://qiita.com/kaneshin/items/0d19fc1cd86f931dc855)

ただ、こちらは手元でも検証リポジトリを作ってやってみたが、大変な作業だった。

また、いずれにも書いてあるが **この操作はコミット履歴を破壊的に変更します** ということなので実施する場合にも注意が必要。

[git count-objects](https://git-scm.com/docs/git-count-objects) や [git gc](https://git-scm.com/docs/git-gc) コマンドについては存在を知らず、これらコマンドについて知れて良かった。

以下の記事なども参考になりそう。

[git gc の仕組みを原理から理解してサイズを 136MB → 7.2MB(95%減)まで削減した時の勉強メモ](https://zenn.dev/ulwlu/articles/cc2443d32e2444)