なぜ .git は小さくならないのか

Gitの作業環境には、少なくとも三つの場所があります。committreeblobを保存するオブジェクトデータベース、次のコミット候補を管理するインデックス、エディタやビルドツールが実際に読む作業ツリー(Working tree)です。

Sparse-checkoutが主に変えるのは、いちばん外側の作業ツリーです。対象外の追跡済みファイルを作業ディレクトリへ置かず、インデックスのskip-worktree情報によって「見えていないが削除されたわけではない」状態にします。

Object database(オブジェクトDB)
コミット、ツリー、blobを保存する。リポジトリの履歴とファイル内容が残る。
partial clone
Index(インデックス)
次のコミットへ入れる内容と、作業ツリーとの対応を管理する。
sparse index
Working tree(作業ツリー)
エディタ、検索、ファイル監視、ビルドが直接触るファイルを置く。
sparse-checkout
作業場所
ブランチごとの作業ツリーとインデックスを分け、同時に開けるようにする。
git worktree
同じ「軽くする」という説明でも、四つの機能は異なる場所に作用します。

対象外のファイルはコミットから消えません。git switchgit commit -aもSparse-checkoutを考慮するため、作業ツリーにないファイルを一斉削除として扱いません。

定義と動作は、Git 2.55.0のgit-sparse-checkout公式マニュアルで確認できます。公式文書は、このコマンド全体を現在もexperimental(実験的)としています。

Sparse-checkoutは倉庫を空にする機能ではありません。巨大な本棚から、いま読む本だけを机へ出す機能です。

そのため、作業ツリーが見通しやすくなっても、過去に取得したblobが.gitへ残るのは想定どおりです。容量の問題を解きたいなら、どの場所が膨らんでいるのかを先に分ける必要があります。

「軽くする」四つの機能が変える場所

たとえば、git statusが遅いことと、クローンに時間がかかることは別の症状です。前者にはインデックスの大きさが関わり、後者には転送するGitオブジェクトが関わります。

困りごと、使う機能、変わるものの対応
困りごと 機能 主に変わるもの 変わらないもの
作業フォルダにファイルが多い Sparse-checkout 作業ツリーへ展開する範囲 既に取得した履歴とオブジェクト
statusaddが重い Sparse index インデックスの表現と処理対象 作業ツリーの選択範囲そのもの
クローン時の転送量が大きい Partial clone 最初に取得するGitオブジェクト 後から必要になったblobの取得
複数ブランチを同時に開きたい Git worktree 作業ツリー、HEAD、インデックス 共有するGitオブジェクトと多くの参照情報(refs)

さらに、node_modulesやビルド成果物の増加はGit管理外ファイルの問題です。パッケージマネージャーの共有ストアやビルドキャッシュで扱うもので、Sparse-checkoutだけでは共有されません。

過去の巨大バイナリが履歴を圧迫しているなら、Git LFSや履歴移行を検討します。作業ディレクトリだけを絞っても、既に保存された履歴は変わりません。

Cone mode(コーンモード)では何が見えるのか

Sparse-checkoutは、既定のCone modeではディレクトリ単位で範囲を指定します。個別ファイルを複雑なパターンで選ぶNon-cone modeも残っていますが、公式文書は非推奨としています。

モノレポ全体

product/
├── README.md
├── package.json
├── apps/
│   ├── package.json
│   ├── web/
│   ├── mobile/
│   └── desktop/
├── services/
│   ├── api/
│   └── billing/
└── packages/
    ├── ui/
    └── contracts/

apps/webを選んだ後

product/
├── README.md
├── package.json
└── apps/
    ├── package.json
    └── web/

指定していないREADME.mdpackage.jsonが残っても、不具合ではありません。Cone modeはリポジトリ直下のファイルと、指定ディレクトリへ至る祖先ディレクトリの直下にあるファイルを含めます。

この規則があるため、ルートの設定ファイルやapps/package.jsonを保ったまま、apps/mobile以下を作業ツリーから外せます。ディレクトリを一つ指定したら、そのパス以外がすべて消えるわけではありません。

対象ディレクトリを設定する
git sparse-checkout set apps/web packages/ui packages/contracts

この範囲変更はignoredファイルを削除する場合があります。変更中ファイルとignoredファイルを確認し、必要なローカルデータを退避してから実行します。

対象を増やすときはgit sparse-checkout addを使います。対象を減らす専用のremoveはないため、残したいディレクトリの完全な一覧をsetし直します。

マージやrebaseの競合処理で対象外ファイルが現れた場合は、競合を解消してからgit sparse-checkout reapplyを実行します。通常のcheckoutへ戻すときはgit sparse-checkout disableですが、すべての追跡済みファイルを再展開できる空き容量を先に確認します。

古い解説にあるgit sparse-checkout init --coneは、現在の標準手順ではありません。Git 2.55.0の公式マニュアルではinitは非推奨で、将来削除される可能性があると説明されています。

AI並行開発で中心になるのはworktree

一つのモノレポでWeb画面、API、E2Eテストを同時に進めると、ファイル数より先に作業場所が衝突します。同じ作業ツリーで片方がブランチを切り替えれば、もう片方の未コミット変更も影響を受けます。

Sparse-checkoutは、各タスクに見せるファイルを絞れます。しかし、同じ作業ツリーを複数タスクが共有する問題までは解きません。並行作業を物理的に分ける中心はgit worktreeです。

三つの並行タスクへ割り当てるブランチ、作業ツリー、Sparse範囲の例
タスク ブランチ 作業ツリー 表示する主な範囲
Web画面 ai/frontend product-ai-frontend apps/webpackages/uipackages/contracts
API ai/backend product-ai-backend services/apipackages/contracts
E2E ai/e2e product-ai-e2e tests/e2eapps/webservices/api

運用単位を一つのタスク、一つのブランチ、一つの作業ツリー、一つのSparse範囲にそろえると、変更が混ざる場所を特定しやすくなります。ただし、これは権限分離ではありません。

worktreeは作業ツリー、HEAD、インデックス、Sparse設定を分けますが、Gitオブジェクトや多くの参照情報(refs)を共有します。対象外の内容もgit showで参照でき、Sparse設定自体も変更できます。AIエージェントから秘密情報を隠す用途には、別のリポジトリ権限と隔離した実行環境が必要です。

git-worktree公式マニュアルは、同じリポジトリへ複数の作業ツリーを接続する仕組みと、checkout前にSparse設定を行う--no-checkoutを説明しています。

効果が出るリポジトリの条件

Sparse-checkoutの価値は、リポジトリの大きさだけでは決まりません。大きな一つのリポジトリに半独立の領域があり、一つのタスクが触る範囲を限定できるときに候補になります。

Web、モバイル、API、インフラストラクチャが同居し、共有する型定義やUIパッケージだけを横断するモノレポは典型例です。リポジトリを分割せず、タスクの作業ツリーだけを小さくできます。

一方、フロントエンドとバックエンドが既に別リポジトリで、どちらも十分小さいなら、管理するSparse範囲一覧が増えるだけかもしれません。全体検索や大規模なリファクタリングを頻繁に行うチームも、通常のcheckoutの方が単純です。

もう一つの境界はビルドです。全package.jsonを探索するスクリプト、全サービスから生成物を作る処理、全ソースを読むライセンス検査は、対象外ファイルがないと正しく動かない場合があります。導入前に、ビルドとIDEが必要とする範囲を確認します。

既存リポジトリで安全に試す

最初に確認するのは、Sparse-checkoutの設定ではありません。いま作業ツリーにしか存在しないデータです。

Gitの版、変更中ファイル、ignoredファイルを順に確認します。チーム、CI、AI実行環境でGitの版が異なる場合は、その差も記録します。

事前確認
git --version
git status --short
git status --short --ignored

変更をコミットするか退避し、ignoredデータをバックアップしたら、最初はsparse indexを付けずに範囲を設定します。作業ツリーを絞る機能と、インデックスを圧縮する実験的な最適化を同時に入れないためです。

最小構成で開始
git sparse-checkout set apps/web packages/ui packages/contracts
git sparse-checkout list
git status --short

listの出力と、必要な設定ファイルが残っていることを確かめます。ビルド、テスト、IDE、Git GUIも普段の操作で確認します。足りないディレクトリはaddで増やし、範囲を狭めるときは新しい完全な一覧をsetします。

対象の追加と再適用
git sparse-checkout add services/mock-api
git sparse-checkout reapply

対象外に残ったファイルを調べる場合、Git 2.52で追加されたcleanのdry-runを使えます。次のコマンドは削除せず、対象ディレクトリと内部のファイルを表示します。

削除候補だけを確認
git sparse-checkout clean --dry-run --verbose

実際の削除には強制オプションが必要ですが、記事の共通手順にはしません。表示されたパスを一件ずつ確認し、バックアップと変更状態を再確認してから、公式マニュアルの説明に沿って個別に判断します。

Sparse-checkout公式マニュアルはignoredファイルの削除条件とcleanの挙動を説明しています。追加時期はGit 2.52.0リリースノートで確認できます。

Sparse-checkoutをやめるときはgit sparse-checkout disableを使います。すべての追跡済みファイルが作業ツリーへ戻るため、巨大リポジトリでは空き容量と展開時間を先に見積もります。

新規クローンではpartial cloneを組み合わせる

まだリポジトリを取得していないなら、作業ツリーだけでなく初期転送量も絞れます。git clone --sparseは最初にリポジトリ直下のファイルだけを展開し、--filter=blob:noneはファイル内容であるblobを必要になるまで取得しません。

新規クローンの例
git clone --filter=blob:none --sparse <REPOSITORY_URL> product
cd product
git sparse-checkout set apps/web packages/ui packages/contracts

二つのオプションは同じ効果を重ねているのではありません。--sparseは作業ツリーの初期状態を決め、--filter=blob:noneはリモートから受け取るオブジェクトを絞ります。

Partial cloneはblobを永久に省く仕組みではありません。checkoutや履歴表示で未取得オブジェクトが必要になると、Gitはpromisor remoteへ接続して取得します。作業を続けるほど.gitの容量は増え得ます。

したがって、オフラインで全履歴を参照する必要がある環境には慎重に適用します。リモート側の対応、追加通信、認証、回線遅延も運用条件に入ります。

オプションの定義はgit-clone公式マニュアル、後からオブジェクトを取得する仕組みと制約はPartial clone設計文書で確認できます。

Sparse indexは動作確認の後に追加する

作業ツリーのファイルを減らしても、通常のインデックスにはリポジトリ全体のファイルエントリが残ることがあります。大きなモノレポでは、git statusgit addがインデックス全体を扱う負荷も無視できません。

Sparse indexは、対象外ディレクトリのファイルエントリをtree単位へまとめます。作業ツリーをさらに減らす機能ではなく、インデックスの表現をSparse範囲へ近づける機能です。

通常のindex
services/billing/a.go
services/billing/b.go
services/billing/internal/c.go

Sparse index
services/billing/

Git 2.55.0ではSparse indexは既定で無効で、公式上もexperimental(実験的)です。古いGit、IDE、Git GUI、独自ツールがSparseディレクトリエントリを理解できない場合があります。

まずSparse-checkoutだけで日常操作を確認し、その後に有効化します。問題があれば作業ツリーの範囲を維持したまま通常インデックスへ戻せます。

Sparse indexを有効にする
git sparse-checkout reapply --sparse-index
通常インデックスへ戻す
git sparse-checkout reapply --no-sparse-index

速度はリポジトリ構造、選択範囲、実行するコマンドによって変わります。一部のコマンドが遅くなる可能性も公式文書に記載されているため、特定環境のベンチマークを一般化せず、実際の操作を計測します。

AI用worktreeへSparse範囲を適用する

Git worktreeの--no-checkoutは、コミットを展開する前にSparse-checkoutなどの設定を行うためのオプションです。既存の作業場所を使い回さず、AIタスク用のブランチとディレクトリを新しく作ります。

新しいAI用worktreeの例
git fetch origin
git worktree add --no-checkout -b ai/frontend ../product-ai-frontend origin/main
git -C ../product-ai-frontend sparse-checkout set apps/web packages/ui packages/contracts
git -C ../product-ai-frontend status --short
git worktree list

この例はブランチ名、基準ブランチ、作成先パスが空いていることを確認してから実行します。既存パスや既にcheckout中のブランチを強制的に上書きする手順ではありません。

既存の変更を強制的に破棄してHEADへ合わせる操作は、通常手順に含めていません。set自体が必要な設定とWorking treeの更新を行うためです。

作業完了後は変更をコミットし、Pull Requestやマージの状態を確認してからgit worktree removeで削除します。未コミットの変更があるworktreeは通常の削除をGitが拒否するため、その安全装置を強制的に迂回しない運用にします。

チームで範囲を共有するなら、改行区切りのディレクトリ一覧をリポジトリへ置き、git sparse-checkout set --stdinで適用できます。共有パッケージを加え忘れたときはプロファイルを直し、各自の手入力だけで差を抱えないようにします。

見えない場所で起きる問題

Working treeから見えなくなったことは、削除されたことも、保護されたことも意味しません。この違いを忘れると、範囲を絞った後の事故を説明できなくなります。

Ignoredファイルは「Git管理外だから残る」とは限らない

Cone modeで範囲を変えると、対象外ディレクトリの中身をGitが調べます。ignoredではない未追跡ファイルがあれば削除せず警告しますが、ignoredファイルしか残っていなければディレクトリごと削除され得ます。

.gitignoreはバックアップ機能ではありません。ローカルDB、秘密情報、アップロードデータをリポジトリ外へ退避してからsetを変更します。

Mergeとrebaseでは対象外ファイルが現れる

競合を表示するため、GitがSparse範囲外のファイルを一時的に展開する場合があります。競合を解消し、変更をコミットまたは退避してからgit sparse-checkout reapplyで現在の範囲を再適用します。

git add --sparseを通常操作にしない

通常のgit addはSparse範囲外のインデックスエントリを更新しないよう警告します。--sparseでその制限を越えられますが、対象外ファイルは後で作業ツリーから消える可能性があります。

範囲外を編集する必要が生じたら、先にgit sparse-checkout addで対象へ含める方が作業状態を追いやすくなります。オプションの意図はgit-add公式マニュアルで確認できます。

サブモジュールは別に状態を持つ

Sparse範囲を変えても、既にcheckoutしたサブモジュールが自動で片付くわけではありません。強制的なdeinitはサブモジュール内の変更や未追跡ファイルを失う可能性があるため、共通レシピには含めず、対象サブモジュールの状態を個別に確認します。

ビルドは存在しないディレクトリを待っているかもしれない

全ワークスペースを走査するビルド、全スキーマからコードを作る生成処理、全ソースを読むライセンス検査は、Sparse範囲だけでは完結しない場合があります。コマンドが成功したことだけでなく、必要な入力とテストが省かれていないことを確かめます。

Worktreeを増やすとGit管理外の容量は増える

worktreeが共有するのはGitオブジェクトです。node_modulesdist.nextcoverage、仮想環境、ローカルDBはworktreeごとに作られます。

ディスク使用量の中心が依存パッケージやビルド成果物なら、パッケージマネージャーの共有ストアとビルドキャッシュを組み合わせます。Sparse-checkoutで解決する対象へ無理に含めません。

秘密情報を見せない境界にはならない

対象外のファイルはgit showなどで参照でき、Sparse設定も変更できます。秘密情報はリポジトリへ置かず、シークレット管理、リポジトリ権限、サンドボックス、実行環境の分離で制御します。

GitHub Actionsでは限定されたジョブに絞る

actions/checkout@v7は、改行区切りのsparse-checkout入力を持ち、Cone modeを既定で有効にします。特定アプリだけをテストするジョブなら、checkout範囲をジョブの入力へ合わせられます。

部分テスト用のワークフロー例
steps:
  - uses: actions/checkout@v7
    with:
      sparse-checkout: |
        apps/web
        packages/ui
        packages/contracts
      sparse-checkout-cone-mode: true

  - run: npm ci
  - run: npm test

ただし、filter入力を指定すると、actions/checkoutではその設定がsparse-checkoutを上書きします。二つの入力を書けば自動的にpartial cloneとSparse-checkoutが合成される、という設定ではありません。

リリースビルド、リポジトリ全体のlint、ライセンス検査、セキュリティ検査、コード生成の整合性確認、全体E2Eでは完全checkoutを残す判断があります。CIが速くなっても、必要な検査まで見えなくなれば成功ではありません。

現在の入力と例はactions/checkout公式リポジトリで確認できます。2026年7月17日時点の最新リリースはv7.0.0です。

Sparse-checkoutを使わない方がよいケース

導入判断は、使えるかどうかだけでは決まりません。設定と範囲一覧を保守する負担が、減らせる作業量より大きいなら、通常のcheckoutを保つ方が安全です。

状況ごとの判断と代わりに検討する方法
状況 判断 理由または代替
リポジトリが小さい 通常は使わない 範囲管理の手間に対して減らせるファイルが少ない。
フロントエンドとバックエンドが既に別リポジトリ 通常は使わない 作業範囲が既に分かれ、横断変更も少ないなら効果が小さい。
毎回リポジトリ全体を変更する 使わないか一時解除 全体検索、移行、大規模リファクタリングでは完全checkoutが分かりやすい。
ビルドが全ファイルを必要とする 使わない 入力不足を速度改善と取り違えない。ジョブやキャッシュを見直す。
IDEやGit GUIがSparse index非対応 Sparse indexだけ外す Sparse-checkoutを維持し、通常indexへ戻せる。
過去の巨大バイナリが問題 別の問題 Git LFSや履歴移行を検討する。
秘密情報を隠したい 使用不可 権限、シークレット管理、隔離した実行環境で制御する。
オフラインで全履歴が必要 Partial cloneを避ける 未取得オブジェクトの追加取得に接続が必要になる。

使わない判断は、Sparse-checkoutの失敗ではありません。解くべき問題が作業ツリー以外にあると分かった結果です。

.gitが残る意味

冒頭でファイル数を減らした後、.gitがほとんど小さくならなかったのは、設定ミスではありませんでした。Sparse-checkoutが狙った作業ツリーだけを変えた結果です。

エディタが読むファイル、検索範囲、ファイル監視の対象を減らしたいなら、その変化には意味があります。クローン時の転送量も抑えたいならpartial cloneを加え、インデックスの処理が重いなら互換性を確認してsparse indexを試し、並行ブランチが衝突するならworktreeを分けます。

巨大なリポジトリを無理に分割する前に、困っている場所を一つ選びます。作業ツリーが問題なら、Sparse-checkoutはリポジトリ全体を保ったまま、いまのタスクに必要な範囲だけを机へ出せます。

公式資料

仕様とリリース情報は2026年7月17日に公式文書で確認しました。Gitの挙動とGitHub Actionsの入力は更新されるため、導入時には利用中の版の文書を再確認してください。

  1. Git sparse-checkout 2.55.0 作業ツリーの定義、Cone mode、Sparse index、ignoredファイル、clean、experimental表記を確認。
  2. Git clone --sparse--filter=blob:noneの定義を確認。
  3. Git Partial clone design notes promisor remote、未取得オブジェクトの追加fetch、オフライン時の制約を確認。
  4. Git worktree 複数Working treeの共有範囲と--no-checkoutの用途を確認。
  5. Git add Sparse範囲外のインデックス項目と--sparseの扱いを確認。
  6. Git 2.52.0 Release Notes git sparse-checkout cleanの追加時期を確認。
  7. actions/checkout sparse-checkout、Cone modeの既定値、filterによる上書きを確認。
  8. actions/checkout v7.0.0 2026年6月18日公開のリリース情報を確認。