T-CREATOR

Git の部分取得を徹底比較:sparse-checkout/partial clone/shallow の違いと使い分け

Git の部分取得を徹底比較:sparse-checkout/partial clone/shallow の違いと使い分け

大規模なリポジトリをクローンするとき、「全部ダウンロードするのに時間がかかりすぎる」「ディスク容量を圧迫する」といった問題に直面したことはありませんか?

Git には、リポジトリの一部だけを取得できる強力な機能が複数用意されています。それが sparse-checkoutpartial clone(部分クローン)、そして shallow clone(浅いクローン) です。これらはそれぞれ異なるアプローチでリポジトリサイズを削減しますが、どの機能をどんなときに使えばよいのか、明確に理解している方は少ないかもしれません。

この記事では、3 つの部分取得機能の違いを徹底的に比較し、実際の利用シーンに応じた使い分け方を解説します。それぞれの仕組みと特徴を図解を交えて整理することで、あなたのプロジェクトに最適な選択肢が見つかるはずです。

背景

Git は分散型バージョン管理システムとして設計されており、通常はリポジトリの 全履歴・全ファイル をローカルにクローンします。これにより、オフラインでも完全な履歴を参照でき、高速なブランチ操作が可能になります。

しかし、プロジェクトが大規模化すると、以下のような課題が顕在化してきました。

  • リポジトリサイズの肥大化: 数年分の履歴や大量のバイナリファイルにより、数 GB を超えるリポジトリも珍しくありません。
  • クローン時間の増大: ネットワーク帯域や処理時間の制約により、初回クローンに数十分かかるケースもあります。
  • ディスク容量の圧迫: 開発者のローカル環境や CI/CD 環境で、ストレージを圧迫する要因となります。

これらの背景から、Git は段階的に部分取得機能を導入してきました。以下の図は、従来の完全クローンと部分取得の概念的な違いを示しています。

以下の図で、従来の完全クローンと部分取得のアプローチを比較してみましょう。

mermaidflowchart LR
  remote["リモートリポジトリ<br/>(全履歴・全ファイル)"]

  subgraph complete ["完全クローン"]
    local1["ローカルリポジトリ<br/>(全履歴・全ファイル)"]
  end

  subgraph partial ["部分取得"]
    local2["ローカルリポジトリ<br/>(必要な部分のみ)"]
  end

  remote -->|全データ転送| local1
  remote -->|必要な部分のみ転送| local2

図で理解できる要点

  • 完全クローンはリモートの全データを転送する
  • 部分取得は必要な部分だけを選択的に転送する
  • データ転送量とストレージ使用量を大幅に削減できる

このような背景を踏まえ、Git は 3 つの異なる部分取得手法を提供しています。

課題

大規模リポジトリでの開発では、以下のような具体的な課題が発生します。

課題 1:全ファイルが不要なのに全部クローンしてしまう

モノレポ(monorepo)構成では、複数のプロジェクトやサービスが 1 つのリポジトリに含まれています。開発者は自分が担当する一部のディレクトリだけを編集したいのに、関係のないディレクトリまで全てクローンされてしまいます。

課題 2:古い履歴が不要なのに全履歴を取得してしまう

CI/CD パイプラインや一時的な作業では、最新のコードだけがあれば十分なケースが多いです。しかし、デフォルトでは何年も前のコミット履歴まで全て取得されるため、無駄な時間とストレージを消費します。

課題 3:大きなバイナリファイルがリポジトリに含まれる

画像、動画、ビルド成果物などの大きなバイナリファイルが履歴に含まれると、リポジトリサイズが急増します。これらのファイルが必要ない環境でも、全て取得されてしまうのです。

以下の図は、これら 3 つの課題を視覚化したものです。

mermaidflowchart TD
  repo["大規模リポジトリ"]

  repo --> issue1["課題 1: 不要なディレクトリ<br/>全ファイルをクローン"]
  repo --> issue2["課題 2: 古い履歴<br/>全履歴を取得"]
  repo --> issue3["課題 3: 大きなバイナリ<br/>全オブジェクトを取得"]

  issue1 --> result1["ディスク容量の無駄"]
  issue2 --> result2["クローン時間の増大"]
  issue3 --> result3["ネットワーク帯域の圧迫"]

  result1 --> problem["開発効率の低下"]
  result2 --> problem
  result3 --> problem

図で理解できる要点

  • 3 つの異なる課題が存在する(ディレクトリ・履歴・オブジェクト)
  • それぞれが異なる形で開発効率を低下させる
  • 課題ごとに適切な解決策が必要

これらの課題に対し、Git は 3 つの異なるアプローチで解決策を提供しています。

解決策

Git の 3 つの部分取得機能は、それぞれ異なる課題にフォーカスして設計されています。以下で各機能の仕組みと特徴を詳しく見ていきましょう。

sparse-checkout(スパースチェックアウト)

sparse-checkout は、ワーキングツリーに展開するファイルを制限 する機能です。リポジトリの全履歴はクローンしますが、実際にディスク上に展開されるファイルを限定できます。

仕組み

sparse-checkout は .git​/​info​/​sparse-checkout ファイルにパターンを記述することで、どのファイルをワーキングツリーに展開するかを制御します。Git 2.25 以降では、cone モードという高速な方式も利用できます。

以下は sparse-checkout の基本的な設定例です。

bash# sparse-checkout を有効化
git sparse-checkout init --cone

次に、必要なディレクトリを指定します。

bash# 特定のディレクトリのみをチェックアウト
git sparse-checkout set src/frontend

設定を確認するには以下のコマンドを使います。

bash# 現在の sparse-checkout 設定を確認
git sparse-checkout list

特徴

#項目内容
1削減対象ワーキングツリーのファイル数
2履歴の取得全履歴を取得する
3後から変更簡単に追加・削除可能
4適用シーンモノレポで特定ディレクトリのみ作業

メリット・デメリット

メリット

  • ワーキングツリーのファイル数を大幅に削減できる
  • 必要なディレクトリを後から簡単に追加できる
  • ローカルでの検索や IDE のインデックス作成が高速化される

デメリット

  • 全履歴を取得するため、リポジトリサイズ自体は削減されない
  • .git ディレクトリのサイズは通常のクローンと変わらない

partial clone(部分クローン)

partial clone は、特定のオブジェクトをクローン時に取得しない 機能です。必要になったときにオンデマンドで取得する「遅延フェッチ」の仕組みを採用しています。

仕組み

partial clone では、フィルタを指定することで取得するオブジェクトを制限します。主なフィルタは以下の通りです。

#フィルタ説明
1blob:noneBlob(ファイル内容)を取得しない
2blob:limit=<size>指定サイズ以上の Blob を取得しない
3tree:0Tree オブジェクトを取得しない

以下は、Blob を取得しない部分クローンの例です。

bash# Blob を取得しない部分クローン
git clone --filter=blob:none https://github.com/example/repo.git

大きなファイルのみをフィルタする場合は以下のようにします。

bash# 1MB 以上の Blob を取得しない
git clone --filter=blob:limit=1m https://github.com/example/repo.git

必要なファイルは後から取得できます。

bash# 必要なファイルを後から取得
git checkout main
# 自動的に必要な Blob がフェッチされる

特徴

#項目内容
1削減対象オブジェクトデータベースのサイズ
2履歴の取得コミット履歴は取得するが、Blob は遅延取得
3後から変更フィルタ変更は困難(再クローン推奨)
4適用シーン大きなバイナリファイルが多いリポジトリ

メリット・デメリット

メリット

  • リポジトリサイズを大幅に削減できる(特に大きなバイナリがある場合)
  • 初回クローン時間が短縮される
  • 必要なファイルだけをオンデマンドで取得できる

デメリット

  • ファイルアクセス時にネットワーク接続が必要になる場合がある
  • オフライン環境では一部の操作が制限される
  • すべての Git ホスティングサービスが対応しているわけではない

shallow clone(浅いクローン)

shallow clone は、コミット履歴の深さを制限 する機能です。最新の数コミットだけを取得することで、リポジトリサイズを削減します。

仕組み

--depth オプションで取得するコミット数を指定します。最も一般的なのは --depth 1 で、最新のコミットのみを取得します。

以下は、最新のコミットのみをクローンする例です。

bash# 最新のコミットのみをクローン
git clone --depth 1 https://github.com/example/repo.git

過去 10 コミットまで取得する場合は以下のようにします。

bash# 過去 10 コミットを取得
git clone --depth 10 https://github.com/example/repo.git

浅いクローンを後から深くすることも可能です。

bash# 浅いクローンを深くする
git fetch --unshallow

特定のブランチのみを浅くクローンすることもできます。

bash# 特定ブランチのみを浅くクローン
git clone --depth 1 --branch main --single-branch https://github.com/example/repo.git

特徴

#項目内容
1削減対象コミット履歴の深さ
2履歴の取得指定した深さまでの履歴のみ取得
3後から変更--unshallow で全履歴を取得可能
4適用シーンCI/CD、一時的な作業環境

メリット・デメリット

メリット

  • クローン時間を大幅に短縮できる
  • リポジトリサイズを削減できる
  • CI/CD パイプラインで高速化できる

デメリット

  • 古いコミットの履歴を参照できない
  • 一部の Git 操作が制限される(git blame の範囲など)
  • ブランチ間の分岐点を正確に特定できない場合がある

3 つの機能の比較

以下の図は、3 つの部分取得機能がそれぞれどの部分を削減するかを示しています。

mermaidflowchart TD
  git["Git リポジトリ"]

  git --> work["ワーキングツリー<br/>(ファイル実体)"]
  git --> objects["オブジェクトDB<br/>(Blob/Tree/Commit)"]
  git --> history["コミット履歴<br/>(過去のコミット)"]

  work -->|削減| sparse["sparse-checkout"]
  objects -->|削減| partial["partial clone"]
  history -->|削減| shallow["shallow clone"]

  sparse --> use1["モノレポの<br/>一部ディレクトリ作業"]
  partial --> use2["大きなバイナリ<br/>ファイルの削減"]
  shallow --> use3["CI/CD<br/>最新コードのみ必要"]

図で理解できる要点

  • 3 つの機能は削減対象が異なる
  • sparse-checkout はワーキングツリー、partial clone はオブジェクト、shallow clone は履歴を削減
  • 目的に応じて適切な機能を選択する

以下の表で、3 つの機能を詳しく比較しましょう。

#項目sparse-checkoutpartial cloneshallow clone
1削減対象ワーキングツリーオブジェクトデータコミット履歴
2.git サイズ削減なし大幅削減削減
3ワーキングツリー削減削減なし削減なし
4履歴参照全履歴可能全履歴可能制限あり
5オフライン作業完全対応制限あり完全対応
6後から拡張容易可能可能
7Git バージョン2.25+ 推奨2.19+1.9+
8主な用途モノレポ大きなバイナリCI/CD

具体例

ここでは、実際の開発シーンに応じた使い分けの例を紹介します。

ケース 1:モノレポで特定のサービスだけ開発

大規模なモノレポで、複数のサービスが以下のような構成になっているとします。

plaintextrepo/
├── services/
│   ├── frontend/
│   ├── backend/
│   ├── mobile/
│   └── admin/
├── shared/
└── docs/

あなたは frontend だけを開発したい場合、sparse-checkout を使います。

bash# リポジトリをクローン
git clone https://github.com/example/monorepo.git
cd monorepo
bash# sparse-checkout を有効化(cone モード)
git sparse-checkout init --cone
bash# frontend と shared のみをチェックアウト
git sparse-checkout set services/frontend shared

この設定により、ワーキングツリーには services​/​frontendshared のみが展開されます。

bash# 確認
git sparse-checkout list
# 出力:
# services/frontend
# shared

後から admin も必要になった場合は、簡単に追加できます。

bash# admin を追加
git sparse-checkout add services/admin

以下の図は、sparse-checkout によるディレクトリの絞り込みを示しています。

mermaidflowchart LR
  remote["リモートリポジトリ<br/>(全ディレクトリ)"]

  subgraph local ["ローカルリポジトリ"]
    git[".git<br/>(全履歴・全ファイル)"]

    subgraph working ["ワーキングツリー"]
      frontend["services/frontend/"]
      shared["shared/"]
    end
  end

  remote -->|clone| git
  git -->|sparse-checkout| working

図で理解できる要点

  • .git には全データが保存されている
  • ワーキングツリーには指定したディレクトリのみが展開される
  • 全履歴にアクセスできるため、任意のコミットを参照可能

ケース 2:大きな画像ファイルが大量にあるリポジトリ

ドキュメントリポジトリで、過去の画像ファイルが大量に蓄積されているケースを考えます。通常のクローンでは数 GB になりますが、画像ファイルは必要なときだけ取得したいとします。

bash# Blob を取得しない部分クローン
git clone --filter=blob:none https://github.com/example/docs.git
cd docs

この時点では、Blob(ファイル内容)は取得されていません。

bash# ブランチをチェックアウト
git checkout main
# 必要な Blob が自動的にフェッチされる

特定のファイルにアクセスすると、その Blob だけが取得されます。

bash# 特定ファイルを編集
vim README.md
# README.md の Blob が自動取得される

大きなファイルのみをフィルタすることもできます。

bash# 10MB 以上のファイルを除外
git clone --filter=blob:limit=10m https://github.com/example/docs.git

以下の図は、partial clone のオンデマンド取得の流れを示しています。

mermaidsequenceDiagram
  participant User as 開発者
  participant Local as ローカルリポジトリ
  participant Remote as リモートリポジトリ

  User->>Local: git clone --filter=blob:none
  Remote->>Local: コミット履歴 + Tree のみ
  Note over Local: Blob は未取得

  User->>Local: git checkout main
  Local->>Remote: 必要な Blob を要求
  Remote->>Local: 要求された Blob のみ送信
  Note over Local: 必要な Blob のみ取得

  User->>Local: cat image.png
  Local->>Remote: image.png の Blob を要求
  Remote->>Local: image.png の Blob を送信

図で理解できる要点

  • 初回クローン時は Blob を取得しない
  • ファイルアクセス時に必要な Blob だけを取得
  • ネットワーク転送量を大幅に削減できる

ケース 3:CI/CD で最新コードだけビルド

GitHub Actions や GitLab CI などの CI/CD パイプラインでは、最新のコードだけがあれば十分です。過去の履歴は不要なため、shallow clone を使います。

GitHub Actions の例を見てみましょう。

yaml# .github/workflows/build.yml
name: Build

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
yamlsteps:
  # 最新のコミットのみをチェックアウト
  - uses: actions/checkout@v4
    with:
      fetch-depth: 1
yaml# ビルド処理
- name: Install dependencies
  run: yarn install

- name: Build
  run: yarn build

コマンドラインで直接実行する場合は以下のようにします。

bash# CI/CD 環境での浅いクローン
git clone --depth 1 --single-branch --branch main https://github.com/example/app.git
cd app
yarn install
yarn build

この方法により、クローン時間を 10 分の 1 以下に短縮できるケースもあります。

以下の図は、shallow clone によるクローン時間の短縮を示しています。

mermaidflowchart LR
  remote["リモートリポジトリ<br/>(1000 コミット)"]

  subgraph normal ["通常クローン"]
    local1["ローカル<br/>(1000 コミット)"]
    time1["クローン時間: 5 分"]
  end

  subgraph shallow ["shallow clone"]
    local2["ローカル<br/>(1 コミット)"]
    time2["クローン時間: 30 秒"]
  end

  remote -->|全履歴| local1
  local1 --> time1

  remote -->|最新のみ| local2
  local2 --> time2

図で理解できる要点

  • shallow clone は最新のコミットのみを取得
  • クローン時間を大幅に短縮できる
  • CI/CD 環境で特に効果的

ケース 4:機能の組み合わせ

3 つの機能は組み合わせて使うこともできます。たとえば、モノレポで特定のディレクトリだけを作業し、かつ最新の履歴のみを取得したい場合です。

bash# shallow clone と sparse-checkout の組み合わせ
git clone --depth 1 https://github.com/example/monorepo.git
cd monorepo
bash# sparse-checkout を設定
git sparse-checkout init --cone
git sparse-checkout set services/frontend shared

さらに、大きなバイナリファイルを除外することもできます。

bash# partial clone + shallow clone + sparse-checkout
git clone --depth 1 --filter=blob:limit=1m https://github.com/example/monorepo.git
cd monorepo
git sparse-checkout init --cone
git sparse-checkout set services/frontend shared

この組み合わせにより、以下の効果が得られます。

#機能削減効果
1--depth 1コミット履歴を最小化
2--filter=blob:limit=1m大きなバイナリを除外
3sparse-checkoutワーキングツリーを限定

以下の図は、3 つの機能を組み合わせた場合の削減効果を示しています。

mermaidflowchart TD
  start["通常クローン<br/>(10 GB)"]

  start -->|shallow clone| step1["履歴削減<br/>(8 GB)"]
  step1 -->|partial clone| step2["オブジェクト削減<br/>(3 GB)"]
  step2 -->|sparse-checkout| final["ワーキングツリー削減<br/>(500 MB)"]

  style start fill:#ffcccc
  style final fill:#ccffcc

図で理解できる要点

  • 3 つの機能を組み合わせることで最大の削減効果
  • 段階的に異なる部分を削減していく
  • 最終的に必要最小限のサイズに

まとめ

この記事では、Git の 3 つの部分取得機能を徹底比較しました。それぞれの特徴を改めて整理しましょう。

sparse-checkout

  • 削減対象: ワーキングツリーのファイル数
  • 適用シーン: モノレポで特定ディレクトリのみ作業
  • 特徴: 全履歴にアクセス可能、後から簡単に変更可能

partial clone

  • 削減対象: オブジェクトデータベースのサイズ
  • 適用シーン: 大きなバイナリファイルが多いリポジトリ
  • 特徴: 必要なファイルをオンデマンドで取得、リポジトリサイズを大幅削減

shallow clone

  • 削減対象: コミット履歴の深さ
  • 適用シーン: CI/CD、一時的な作業環境
  • 特徴: クローン時間を大幅短縮、最新コードのみ必要な場合に最適

これらの機能は、それぞれ異なる課題を解決するために設計されています。あなたのプロジェクトの特性や作業内容に応じて、適切な機能を選択してください。また、必要に応じて複数の機能を組み合わせることで、さらなる効率化も可能です。

大規模リポジトリでの開発において、これらの部分取得機能を活用することで、クローン時間の短縮、ディスク容量の節約、そして開発体験の向上が実現できるでしょう。ぜひ、あなたの環境で試してみてください。

関連リンク