Git
日本語 ▾ トピック ▾ 最新バージョン ▾ git-sparse-checkoutは2.42.0で最後に更新されました

名前

git-sparse-checkout - 作業ツリーを追跡ファイルのサブセットに縮小する

概要

git sparse-checkout (init | list | set | add | reapply | disable | check-rules) [<options>]

説明

このコマンドは、スパースチェックアウトを作成するために使用されます。スパースチェックアウトは、作業ツリーにすべての追跡ファイルが存在する状態から、ファイルのサブセットのみが存在する状態に変更します。また、どのファイルのサブセットが存在するかを切り替えたり、元に戻して作業コピーにすべての追跡ファイルが存在する状態に戻したりすることもできます。

ファイルのサブセットは、コーンモード(デフォルト)でディレクトリのリストを提供するか、非コーンモードでパターンのリストを提供することによって選択されます。

スパースチェックアウトでは、他のGitコマンドの動作が少し異なります。たとえば、ブランチを切り替えても、スパースチェックアウトのディレクトリ/パターンの外にあるパスは更新されず、 `git commit -a` は、スパースチェックアウトのディレクトリ/パターンの外にあるパスを削除済みとして記録しません。

このコマンドは実験的です。その動作、およびスパースチェックアウトが存在する場合の他のコマンドの動作は、将来変更される可能性があります。

コマンド

list

スパースチェックアウトファイル内のディレクトリまたはパターンを記述します。

set

必要なスパースチェックアウト設定(`core.sparseCheckout`、`core.sparseCheckoutCone`、および `index.sparse`)がまだ目的の値に設定されていない場合は有効にし、 _set_ サブコマンドに続く引数のリストからスパースチェックアウトファイルを作成し、作業ディレクトリを一致するように更新します。

ワークツリー内でスパースチェックアウト設定を調整しても、他のワークツリーのスパースチェックアウト設定が変更されないようにするために、_set_ サブコマンドは、まだ存在しない場合、ワークツリー固有の設定を使用するようにリポジトリ設定をアップグレードします。 _set_ サブコマンドの引数によって定義されたスパース性は、ワークツリー固有のスパースチェックアウトファイルに保存されます。詳細については、git-worktree[1] および git-config[1] の `extensions.worktreeConfig` のドキュメントを参照してください。

`--stdin` オプションが指定されている場合、ディレクトリまたはパターンは、引数からではなく、標準入力から改行区切りのリストとして読み取られます。

デフォルトでは、入力リストは `git ls-tree -d --name-only` の出力と一致するディレクトリのリストとみなされます。これには、二重引用符( ")で始まるパス名をCスタイルの引用符で囲まれた文字列として解釈することが含まれます。指定されたディレクトリ(任意の深さ)の下にあるすべてのファイル、および指定されたディレクトリまたはその祖先のいずれかの兄弟であるファイルは、スパースチェックアウトに含まれることに注意してください(詳細については、以下の_コーンパターンセット_を参照)。以前は、これはデフォルトではなく、 `--cone` を指定するか、 `core.sparseCheckoutCone` を有効にする必要がありました。

`--no-cone` が渡されると、入力リストはパターンのリストとみなされます。このモードには、 `--sparse-index` のような一部のオプションで動作しないなど、多くの欠点があります。以下の「非コーンの問題」セクションで説明するように、使用することはお勧めしません。

スパースインデックスを使用するには、 `--[no-]sparse-index` オプションを使用します(デフォルトでは使用しません)。スパースインデックスは、インデックスのサイズをスパースチェックアウト定義により厳密に一致するように縮小します。これは、 `git status` や `git add` などのコマンドのパフォーマンスに大きな利点をもたらす可能性があります。この機能はまだ実験段階です。一部のコマンドは、この機能と適切に統合されるまで、スパースインデックスを使用すると遅くなる可能性があります。

**警告:**スパースインデックスを使用するには、外部ツールでは完全には理解されない方法でインデックスを変更する必要があります。この互換性に問題がある場合は、 `git sparse-checkout init --no-sparse-index` を実行して、インデックスがスパースにならないように書き直してください。古いバージョンのGitは、スパースディレクトリエントリインデックス拡張子を理解せず、無効になるまでリポジトリと対話できない場合があります。

_add_

スパースチェックアウトファイルを更新して、追加のディレクトリ(コーンモード)またはパターン(非コーンモード)を含めます。デフォルトでは、これらのディレクトリまたはパターンはコマンドライン引数から読み取られますが、 `--stdin` オプションを使用してstdinから読み取ることもできます。

_reapply_

作業ツリー内のパスにスパース性パターンのルールを再適用します。マージやリベースのようなコマンドは、作業を行うためにパスを具体化することができ(たとえば、競合を表示するため)、他のスパースチェックアウトコマンドは個々のファイルをスパース化できない場合があります(たとえば、ステージされていない変更や競合があるため)。このような場合は、影響を受けるパスをクリーンアップした後(たとえば、競合の解決、変更の取り消しまたはコミットなど)に `git sparse-checkout reapply` を後で実行するのが理に合っています。

`reapply` コマンドは、 `set` コマンドのフラグと同じ意味で、 `--[no-]cone` および `--[no-]sparse-index` フラグも使用できます。これにより、すべてのスパース性パスを再指定することなく、使用しているスパース性モードを変更できます。

_disable_

`core.sparseCheckout` 設定を無効にし、作業ディレクトリを復元してすべてのファイルを含めます。

_init_

パスが指定されていない `set` のように動作する非推奨のコマンド。将来削除される可能性があります。

以前は、 `set` は必要なすべての設定を処理しなかったため、 `init` と `set` の両方呼び出す必要がありました。両方を呼び出すということは、 `init` ステップが最初にほとんどすべての追跡ファイルを削除し(コーンモードでは無視されたファイルも)、次に `set` ステップが追跡ファイルの多く(ただし無視されたファイルは除く)を追加し直すことを意味しました。失われたファイルに加えて、この組み合わせのパフォーマンスとUIは貧弱でした。

また、以前は、 `init` はスパースチェックアウトファイルがすでに存在する場合、実際に初期化しませんでした。これは、後続の_set_または_add_コマンドに渡すパスを覚えていなくても、スパースチェックアウトに戻ることができることを意味しました。ただし、 `--cone` および `--sparse-index` オプションはdisableコマンド全体で記憶されないため、プレーンな `init` を呼び出すことによる簡単な復元は実用性が低下しました。

_check-rules_

スパース性ルールが1つ以上のパスと一致するかどうかを確認します。

デフォルトでは、 `check-rules` はstdinからパスのリストを読み取り、現在のスパース性ルールと一致するものだけを出力します。入力は、1行あたり1つのパスで構成され、二重引用符( ")で始まるパス名がCスタイルの引用符で囲まれた文字列として解釈されることを含め、 `git ls-tree --name-only` の出力と一致することが想定されています。

`--rules-file ` フラグを指定して呼び出された場合、入力ファイルは、現在のルールではなく、 `` にあるスパースチェックアウトルールと照合されます。ファイル内のルールは、 `git sparse-checkout set --stdin` で受け入れられるのと同じ形式であることが想定されています(特に、改行区切りである必要があります)。

デフォルトでは、--rules-file オプションに渡されるルールは、コーンモードのディレクトリとして解釈されます。--rules-file で非コーンモードのパターンを渡すには、このオプションと --no-cone オプションを組み合わせて使用します。

-z フラグを指定して呼び出された場合、stdin で入力されるパスと出力パスの形式は、\0 で終端され、引用符で囲まれません。これは、--rules-file オプションで渡されるルールの形式には適用されないことに注意してください。

git sparse-checkout set MY/DIR1 SUB/DIR2

MY/DIR1/ と SUB/DIR2/ 以下のすべてのファイル(任意の深さ)が作業コピーに存在する(さらに、MY/ と SUB/ の直下のすべてのファイルとトップレベルディレクトリ)疎チェックアウトに変更します。既に疎チェックアウトになっている場合は、作業コピーに存在するファイルをこの新しい選択に変更します。このコマンドは、追跡されたファイルまたは無視されていない追跡されていないファイルが存在しなくなったディレクトリ内のすべての無視されたファイルも削除することに注意してください。

git sparse-checkout disable

すべてのファイルで作業ディレクトリを再作成し、疎チェックアウトを無効にします。

git sparse-checkout add SOME/DIR/ECTORY

SOME/DIR/ECTORY/ 以下のすべてのファイル(任意の深さ)を疎チェックアウトに追加します。また、SOME/DIR/ と SOME/ の直下のすべてのファイルも追加します。このコマンドを使用する前に、既に疎チェックアウトになっている必要があります。

git sparse-checkout reapply

コマンドが、選択された疎ディレクトリを尊重しない方法で作業ツリーを更新する可能性があります。これは、Git の外部ツールがファイルに書き込むことによって発生する可能性があり、特殊なケース(マージ/リベース時の競合の発生など)や、一部のコマンドが疎チェックアウトを完全にサポートしていなかった(例:古い recursive マージバックエンドは限定的なサポートのみ)ため、Git コマンドにも影響を与える可能性があります。このコマンドは、既存の疎ディレクトリ仕様を再適用して、作業ディレクトリを一致させます。

内部 - 疎チェックアウト

「疎チェックアウト」を使用すると、作業ディレクトリにファイルを疎に配置できます。 skip-worktree ビット(git-update-index[1] を参照)を使用して、作業ディレクトリ内のファイルが確認する価値があるかどうかを Git に指示します。 skip-worktree ビットが設定されていて、ファイルが作業ツリーに存在しない場合、その不在は無視されます。 Git はこれらのファイルの内容の配置を回避します。これにより、多くのファイルを含むリポジトリで作業する場合に、現在のユーザーにとって重要なファイルが少数しかない場合に、疎チェックアウトが役立ちます。

$GIT_DIR/info/sparse-checkout ファイルは、skip-worktree 参照ビットマップを定義するために使用されます。 Git が作業ディレクトリを更新すると、このファイルに基づいてインデックス内の skip-worktree ビットが更新されます。ファイル内のパターンに一致するファイルは作業ディレクトリに表示され、残りは表示されません。

内部 - 非コーンモードの問題点

set および add サブコマンドによって設定される $GIT_DIR/info/sparse-checkout ファイルは、.gitignore ファイルと同じ構文を使用して、複数のパターン(1行につき1つ)で定義されます。コーンモードでは、これらのパターンはディレクトリとの一致に制限され(ユーザーはディレクトリ名のみを提供または表示する必要があります)、非コーンモードでは gitignore スタイルのパターンが許可されます。非コーンモードで完全な gitignore スタイルのパターンを使用すると、多くの欠点があります。

  • 基本的に、さまざまな作業ツリー更新プロセス(プル、マージ、リベース、切り替え、リセット、チェックアウトなど)で O(N*M) パターンのマッチングが必要になります。ここで、N はパターンの数、M はインデックス内のパスの数です。これはスケーリングが悪いです。

  • スケーリングの問題を回避するには、先頭のディレクトリ名またはグロブを指定してパターンの数を制限する必要があります。

  • コマンドラインでグロブを渡すと、ユーザーがグロブの引用符を忘れる可能性があり、シェルがそれをすべての一致するファイルに展開し、それらをすべて個別に sparse-checkout set/add に渡してしまうため、エラーが発生しやすくなります。これは、たとえば「git grep -- *.c」でも問題になる可能性がありますが、grep/log/status の間違いはすぐにわかります。 sparse-checkout では、sparse-checkout コマンドの実行時に間違いが記録され、ユーザーが後でブランチを切り替えたり、リベースしたり、マージしたりするまで問題が発生しない可能性があり、ユーザーのエラーとそれを検出/認識する機会との間に遅延が生じます。

  • 前の項目に関連して、sparse-checkout には *add* サブコマンドがありますが、*remove* サブコマンドはありません。 *remove* サブコマンドが追加されたとしても、誤って引用符で囲まれていないグロブを元に戻すと、「削除しすぎる」リスクがあり、誤って追加する前に含まれていたエントリが削除される可能性があります。

  • 非コーンモードでは、gitignore スタイルのパターンを使用して **含める** ものを選択しますが(否定されたパターンを除く)、.gitignore ファイルでは gitignore スタイルのパターンを使用して **除外** するものを選択します(否定されたパターンを除く)。 gitignore スタイルのパターンに関するドキュメントは、通常、一致または不一致ではなく、ユーザーが「除外」したいものについて説明しています。これは、目的の動作を得るために sparse-checkout パターンの指定方法を学習しようとしているユーザーに混乱を招く可能性があります。

  • 「特別なパスパターンマッチング」を提供したい他のすべての git サブコマンドは pathspec を使用しますが、sparse-checkout の非コーンモードは gitignore パターを使用するため、一貫性がありません。

  • 「正しい」動作が不明確なエッジケースがあります。 2つの例

    First, two users are in a subdirectory, and the first runs
       git sparse-checkout set '/toplevel-dir/*.c'
    while the second runs
       git sparse-checkout set relative-dir
    Should those arguments be transliterated into
       current/subdirectory/toplevel-dir/*.c
    and
       current/subdirectory/relative-dir
    before inserting into the sparse-checkout file?  The user who typed
    the first command is probably aware that arguments to set/add are
    supposed to be patterns in non-cone mode, and probably would not be
    happy with such a transliteration.  However, many gitignore-style
    patterns are just paths, which might be what the user who typed the
    second command was thinking, and they'd be upset if their argument
    wasn't transliterated.
    Second, what should bash-completion complete on for set/add commands
    for non-cone users?  If it suggests paths, is it exacerbating the
    problem above?  Also, if it suggests paths, what if the user has a
    file or directory that begins with either a '!' or '#' or has a '*',
    '\', '?', '[', or ']' in its name?  And if it suggests paths, will
    it complete "/pro" to "/proc" (in the root filesystem) rather than to
    "/progress.txt" in the current directory?  (Note that users are
    likely to want to start paths with a leading '/' in non-cone mode,
    for the same reason that .gitignore files often have one.)
    Completing on files or directories might give nasty surprises in
    all these cases.
  • 過度の柔軟性により、他の拡張機能は事実上実用的ではなくなりました。 --sparse-index は非コーンモードでは不可能です。何とか実行可能であったとしても、実装にははるかに多くの作業が必要となり、実際には遅すぎる可能性がありました。部分クローンと疎チェックアウトの間に結合を追加するというアイデアも、より制限されたパスのセットでのみ実用的です。

これらの理由から、非コーンモードは非推奨です。コーンモードの使用に切り替えてください。

内部 - コーンモードの処理

デフォルトの「コーンモード」では、含めるディレクトリのみを指定できます。指定されたディレクトリの場合、そのディレクトリ以下のすべてのパスが含まれ、先頭のディレクトリ(トップレベルディレクトリを含む)の直下のパスも含まれます。したがって、Documentation/technical/ ディレクトリを指定した場合、疎チェックアウトには次のものが含まれます。

  • トップレベルディレクトリ内のすべてのファイル

  • Documentation/ の直下のすべてのファイル

  • Documentation/technical/ 以下の任意の深さのすべてのファイル

また、コーンモードでは、ディレクトリが指定されていない場合でも、トップレベルディレクトリ内のファイルが含まれます。

コーンモードで sparse-checkout パターを変更する場合、Git は sparse-checkout コーン内にない追跡された各ディレクトリを検査して、追跡されていないファイルが含まれているかどうかを確認します。これらのファイルがすべて .gitignore パターンのため無視されている場合、ディレクトリは削除されます。そのディレクトリ内の追跡されていないファイルのいずれかが無視されていない場合、そのディレクトリ内では削除は行われず、警告メッセージが表示されます。これらのファイルが重要な場合は、sparse-checkout 定義をリセットしてそれらを含め、git addgit commit を使用してそれらを保存し、残りのファイルをすべて手動で削除して、Git が最適に動作できるようにします。

ディレクトリが内部で sparse-checkout の完全パターンセットのサブセットにどのように変換されるかについては、「内部 - コーンパターンセット」セクションも参照してください。

内部 - 完全パターンセット

完全パターンセットでは、任意のパターンマッチと複雑な包含/除外ルールが可能です。これにより、インデックスの更新時に O(N*M) パターンのマッチングが発生する可能性があります。ここで、N はパターンの数、M はインデックス内のパスの数です。このパフォーマンスの問題に対処するために、core.sparseCheckoutCone が有効になっている場合は、より制限されたパターンセットが許可されます。

sparse-checkout ファイルは、.gitignore ファイルと同じ構文を使用します。詳細は gitignore[5] を参照してください。ただし、ここでは、パターンは通常、除外するファイルではなく、含めるファイルを選択するために使用されます。(ただし、gitignore スタイルのパターンには *!* で始まるパターンで定義された否定があるため、*含まない* ファイルを選択することもできるため、少し混乱する可能性があります。)

たとえば、すべてを選択してから、ファイル unwanted を削除するには(unwanted という名前のファイルを除くすべてのファイルが作業ツリーに表示されるようにするには)

git sparse-checkout set --no-cone '/*' '!unwanted'

これらのパターンはそのまま $GIT_DIR/info/sparse-checkout に配置されるため、この時点でのそのファイルの内容は次のようになります。

/*
!unwanted

sparse-checkout で使用される gitignore スタイルのパターンの詳細については、git-read-tree[1] の「疎チェックアウト」セクションも参照してください。

内部 - コーンパターンセット

コーンモードでは、ディレクトリのみが受け入れられますが、それらは完全パターンセットで使用されるのと同じ gitignore スタイルのパターンに変換されます。これらのモードで使用される特定のパターンは、次の2つのタイプのいずれかであると呼びます。

  1. **再帰的:** ディレクトリ内のすべてのパスが含まれます。

  2. **親:** ディレクトリの直下のすべてのファイルが含まれます。

コーンモードでは常にトップレベルのファイルが含まれるため、ディレクトリを指定せずに git sparse-checkout set を実行すると、トップレベルディレクトリが親パターンとして追加されます。この時点で、sparse-checkout ファイルには次のパターンが含まれています。

/*
!/*/

これは、「トップレベルディレクトリの直下のすべてを含めるが、それより下のレベルのものは何も含めない」という意味です。

コーンモードでは、git sparse-checkout set サブコマンドはディレクトリのリストを受け取ります。コマンド git sparse-checkout set A/B/C は、ディレクトリ A/B/C を再帰パターンとして設定し、ディレクトリ AA/B を親パターンとして追加します。結果の sparse-checkout ファイルは次のようになります。

/*
!/*/
/A/
!/A/*/
/A/B/
!/A/B/*/
/A/B/C/

ここでは順序が重要であるため、否定パターンはファイルの下位にある肯定パターンによってオーバーライドされます。

core.sparseCheckoutCone が明示的に false に設定されていない限り、Git はこれらのタイプのパターンを期待して sparse-checkout ファイルを解析します。パターンが一致しない場合、Git は警告を発します。パターンが予期される形式と一致する場合、Git は高速なハッシュベースのアルゴリズムを使用して sparse-checkout に含まれるかどうかを計算します。一致しない場合、git は設定に関係なく、core.sparseCheckoutCone が false であったかのように動作します。

コーンモードの場合、完全なパターンが $GIT_DIR/info/sparse-checkout ファイルに書き込まれるという事実にもかかわらず、git sparse-checkout list サブコマンドは再帰パターンを定義するディレクトリをリストします。上記の sparse-checkout ファイルの例では、出力は次のようになります。

$ git sparse-checkout list
A/B/C

core.ignoreCase=true の場合、パターンマッチングアルゴリズムは大文字と小文字を区別しないチェックを使用します。これにより、*git sparse-checkout set* コマンドのファイル名の大文字と小文字の不一致が修正され、作業ディレクトリ内の予期されるコーンが反映されます。

内部 - サブモジュール

リポジトリに1つ以上のサブモジュールが含まれている場合、サブモジュールは git submodule コマンドとの相互作用に基づいて設定されます。具体的には、git submodule init -- <path><path> のサブモジュールが存在することを確認し、git submodule deinit [-f] -- <path><path> のサブモジュールのファイル(追跡されていないファイル、コミットされていない変更、プッシュされていない履歴を含む)を削除します。 sparse-checkout が作業ツリーからファイルを削除するがインデックスにエントリを残すのと同様に、初期化されていないサブモジュールは作業ディレクトリから削除されますが、インデックスにはエントリが残ります。

サブモジュールにはプッシュされていない変更や追跡されていないファイルが存在する可能性があるため、それらを削除するとデータが失われる可能性があります。したがって、スパースな包含/除外ルールを変更しても、既にチェックアウトされているサブモジュールが作業コピーから削除されることはありません。言い換えれば、checkoutは、サブモジュールを削除または追加するブランチ間を切り替える場合でも、サブモジュールを自動的に削除または初期化しないように、sparse-checkoutを使用して「興味深い」ファイルの範囲を縮小または拡張しても、サブモジュールが自動的に初期化解除または初期化されることはありません。

さらに、上記の事実から、「追跡済み」ファイルが作業コピーに存在しない理由は複数あることがわかります。スパースチェックアウトによるスパースパターンの適用と、サブモジュールの初期化状態です。したがって、作業コピー内の追跡対象ファイルに対して動作するgit grepなどのコマンドは、これらの制限のいずれかまたは両方によって制限された結果を返す場合があります。

GIT

git[1] スイートの一部

scroll-to-top