Chromium を git shallow clone したらどの程度サイズが減るか

###### はじめに

[ACCESS Advent Calendar 2018](https://qiita.com/advent-calendar/2018/access) の18日目です。
初めまして、お肉大好き @naohikowatanabe です。今年ハマったお肉屋さんはいきなりステーキです！肉マイレージカードはあと少しでゴールドカードになります。

小ネタ投下します。今週の弊社アドベントカレンダー埋まりが悪いなんて言えn(ry

# git shallow clone とは

git の履歴を減らしてローカルのサイズを減らすことが出来ます。
履歴の少ないリポジトリではあまり気にしなくて良い話ですが、巨大なリポジトリでは時間とサイズ節約に役立ちます。

公式サイトの説明を以下引用します。

https://git-scm.com/docs/git-clone

```
git-clone - Clone a repository into a new directory

--depth <depth>
Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.
--shallow-since=<date>
Create a shallow clone with a history after the specified time.
--shallow-exclude=<revision>
Create a shallow clone with a history, excluding commits reachable from a specified remote branch or tag. This option can be specified multiple times.

---翻訳---

git-clone  - リポジトリを新しいディレクトリにクローン化する

--depth <depth>
特定のコミット数に切り捨てられた履歴を持つ浅いクローンを作成します。
すべてのブランチのヒントの近くにヒストリを取得するために--no-single-branchを指定しない限り、単一ブランチを暗示します。
サブモジュールを浅くクローンしたい場合は、--shallow-submodulesも渡します。
--shallow-since=<date>
指定した時間後に履歴を持つ浅いクローンを作成します。
--shallow-exclude=<revision>
特定のリモートブランチまたはタグから到達可能なコミットを除いて、ヒストリを持つ浅いクローンを作成します。
このオプションは複数回指定できます。
```

https://git-scm.com/docs/git-gc

```
git-gc - Cleanup unnecessary files and optimize the local repository

--aggressive
Usually git gc runs very quickly while providing good disk space utilization and performance. This option will cause git gc to more aggressively optimize the repository at the expense of taking much more time. The effects of this optimization are persistent, so this option only needs to be used occasionally; every few hundred changesets or so.

--prune=<date>
Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable gc.pruneExpire). --prune=all prunes loose objects regardless of their age and increases the risk of corruption if another process is writing to the repository concurrently; see "NOTES" below. --prune is on by default.

---翻訳---

git-gc  - 不要なファイルをクリーンアップし、ローカルリポジトリを最適化する

--aggressive
git gcは非常に速く実行され、ディスクスペースの有効利用とパフォーマンスが良好です。
このオプションを指定すると、git gcはより積極的にリポジトリを最適化します。
この最適化の効果は永続的なものなので、このオプションは時折使用する必要があります。数百のチェンジセットごとに。

--prune=<date>
日付より古いオブジェクトをプルーンします（デフォルトは2週間前、設定変数gc.pruneExpireで上書き可能です）。
--prune=all 他のプロセスが同時にリポジトリに書き込んでいる場合は、オブジェクトの経過時間に関係なく緩いオブジェクトをプルーニングし、破損のリスクを増加させます。下記の「注意事項」を参照してください。
--prune はデフォルトでオンになっています。
```


# 使い方

## パターン1：clone 時に shallow clone

#### 通常の clone (shallow clone 無し)

```
git clone https://github.com/hoge/fuga
```

#### shallow clone 有り

```
git clone --depth 1 https://github.com/hoge/fuga
```

## パターン2：通常 clone するがその後 shallow clone 化

#### 通常 clone 後、 git gc

```
git clone https://github.com/hoge/fuga
git fetch --depth=1
git gc --aggressive --prune=now
```

# Chromium とは

[Chromium](https://www.chromium.org/Home) とはみんな大好き Google Chrome の元となっているオープンソースプロジェクトです。
Chromium はリポジトリが巨大です。
執筆時点で master が73万コミットほど、サイズは13GBほどあります。。。

```
$ git log --oneline | wc -l
737358
$ du -sh .git
13G    .git
```


# Chromium で git shallow clone

```
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
$ export PATH="$PATH:/path/to/depot_tools" 
$ mkdir ./chromium && cd ./chromium
$ fetch --nohooks android
$ cd src/
$ git log --oneline | wc -l
737358
$ du -sh .git
13G    .git
$ git gc --aggressive --prune=now
$ du -sh .git
4.7G    .git
$ git log --oneline | wc -l
1
```

デフォルト13GBが半分以下の4.7Gまで減りました！

# その他注意点

Chromium で shallow clone は寝る前、帰宅前、ご飯前などに実施するのがおすすめです。
時間がかかるのと CPU 使用率、RAM 使用量が跳ね上がるためです。

手元の Ubuntu だと約1時間かかりました。

```
$ time git gc --aggressive --prune=now
Enumerating objects: 4788768, done.
Counting objects: 100% (4788768/4788768), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4639247/4639247), done.
Writing objects: 100% (4788768/4788768), done.
Total 4788768 (delta 4026625), reused 505478 (delta 0)
Checking connectivity: 4788768, done.

real    63m18.634s
user    347m29.104s
sys    2m3.601s
$
```

# 終わりに

明日の担当は @ttokit です。お楽しみに！🎉

# 参考

[公式サイト](https://git-scm.com/docs/git-clone)
[git で shallow clone](https://qiita.com/sonots/items/ce08c30d161ea0b4d5fd)
[git リポジトリの最新の履歴だけを取得する shallow clone](https://qiita.com/usamik26/items/7bfa61b31344206077fb)