shallow cloneは「必要な分だけ持ってくる複製」
Gitのリポジトリを手元に持ってくるとき、普通は git clone を使います。このとき何が起きているかというと、そのプロジェクトが生まれてから今日までのコミット履歴を全部コピーしてきています。1年前に誰が何行直したか、3年前に消されたファイルの中身まで、まるごとです。
shallow clone(シャロークローン、浅いクローン)は、その履歴を途中で打ち切って持ってくるやり方です。「最新のコミット1個分だけあればいい」「直近50件でいい」と指定して、それより古い部分はダウンロードしません。
身近な例えで言うと、雑誌のバックナンバーです。創刊号から最新号まで全部そろえるのが通常のclone。「今月号だけ買えば読める」というのがshallow cloneです。特集記事を読みたいだけなら最新号1冊で十分ですし、そのほうが安いし持ち帰るのも楽ですよね。ただし「3年前の連載を読み返したい」と思ったときには手元にないので、また買いに行く必要があります。
どう書くのか
コマンドは --depth オプションを付けるだけです。
# 最新の1コミットだけ取得
git clone --depth 1 https://github.com/example/repo.git
# 直近50コミット分だけ取得
git clone --depth 50 https://github.com/example/repo.git
--depth 1 が一番よく使われる形です。「今のソースコードの状態だけほしい」というケースに、ぴったり合うからです。
何がうれしいのか
一番大きいのは速さとディスク容量です。歴史の長いプロジェクトだと、実際のソースコードは数十MBなのに、履歴を含めると数GBという状態は珍しくありません。--depth 1 にすると、その差がそのまま転送量の差になります。回線が細い環境や、待ち時間が惜しい場面ではかなり体感が変わります。
通常のclone
全履歴つき。あとから過去のコミットを見たり、履歴をたどった調査ができる。そのぶん重い。
shallow clone
最新付近だけ。速くて軽い。過去をさかのぼる操作は、そのままではできない。
向いている場面・向いていない場面
相性がいいのは、使い捨てのチェックアウトです。CI(自動テストやビルドを回す仕組み)でソースを取ってきてビルドするだけ、という用途はまさにこれ。毎回まっさらな環境で clone するので、履歴を持ってくる意味がほとんどありません。「ドキュメントを読みたいから落とすだけ」「サンプルコードを動かしてみたいだけ」というときも十分です。
逆に向かないのは、長く付き合う開発用のリポジトリです。git log で昔の変更を追いかけたい、git blame でこの行がいつ入ったのか調べたい、git bisect でバグが混入したコミットを二分探索したい——こうした操作は履歴がないと成り立ちません。shallow cloneした直後だと、ログを見ても1件しか出てこなくて「あれ?」となります。これは壊れているのではなく、そもそも持ってきていないだけです。
あとから深くしたいとき
「やっぱり履歴が必要になった」という場合、作り直さなくても後から取り足せます。
# 全履歴を取得して普通のクローンに戻す
git fetch --unshallow
# 段階的に深くする(あと100件ぶん足す)
git fetch --depth 100
なので、迷ったらまず --depth 1 で試して、必要になったら --unshallow、という進め方でも困りません。この「後戻りできる」性質を知っているかどうかで、shallow cloneの使いやすさの印象がだいぶ変わります。
つまずきやすいポイント
ありがちなのが、shallow cloneした状態で作業して、そこからブランチをpushしようとしてうまくいかないケースです。共通の祖先となるコミットが手元にないため、差分の計算が成立しないことがあります。開発作業をするつもりのリポジトリなら、最初から通常のcloneにしておくか、必要になった時点で --unshallow しておくのが無難です。
あと、--depth を付けると既定でデフォルトブランチだけを取ってくる挙動になるため、「別のブランチに切り替えられない」と戸惑うこともあります。特定のブランチが欲しいなら --branch で明示するとはっきりします。
要するにshallow cloneは、Gitの機能を削ったものではなく「今は要らない部分をあとまわしにする」オプションです。何のためにcloneするのかをひと呼吸考えて、履歴が要る作業かどうかで選べば、判断を間違えにくくなります。
このページは役に立ちましたか?