Git
日本語 ▾ トピック ▾ 最新バージョン ▾ git-update-index は 2.46.0 で最終更新

名前

git-update-index - ワーキングツリーのファイルコンテンツをインデックスに登録します

概要

git update-index
	     [--add] [--remove | --force-remove] [--replace]
	     [--refresh] [-q] [--unmerged] [--ignore-missing]
	     [(--cacheinfo <mode>,<object>,<file>)…​]
	     [--chmod=(+|-)x]
	     [--[no-]assume-unchanged]
	     [--[no-]skip-worktree]
	     [--[no-]ignore-skip-worktree-entries]
	     [--[no-]fsmonitor-valid]
	     [--ignore-submodules]
	     [--[no-]split-index]
	     [--[no-|test-|force-]untracked-cache]
	     [--[no-]fsmonitor]
	     [--really-refresh] [--unresolve] [--again | -g]
	     [--info-only] [--index-info]
	     [-z] [--stdin] [--index-version <n>]
	     [--show-index-version]
	     [--verbose]
	     [--] [<file>…​]

説明

インデックスを修正します。指定された各ファイルはインデックスに更新され、未マージまたは更新が必要な状態はクリアされます。

インデックスに対する最も一般的な操作を行うためのよりユーザーフレンドリーな方法については、git-add[1] も参照してください。

git update-index がファイルを取り扱う方法は、さまざまなオプションを使用して変更できます。

オプション

--add

指定されたファイルがインデックスにまだ存在しない場合は、追加されます。デフォルトの動作は、新しいファイルを無視することです。

--remove

指定されたファイルがインデックスに存在し、欠落している場合は、削除されます。デフォルトの動作は、削除されたファイルを無視することです。

--refresh

現在のインデックスを見て、stat() 情報の確認によってマージまたは更新が必要かどうかを確認します。

-q

静音。--refresh でインデックスを更新する必要があることが判明した場合、デフォルトの動作ではエラーが発生します。このオプションを使用すると、git update-index は続行されます。

--ignore-submodules

サブモジュールの更新を試行しません。このオプションは、--refresh の前に渡された場合にのみ尊重されます。

--unmerged

--refresh でインデックスに未マージの変更が見つかった場合、デフォルトの動作ではエラーが発生します。このオプションを使用すると、git update-index は続行されます。

--ignore-missing

--refresh 中に欠落しているファイルを無視します。

--cacheinfo <mode>,<object>,<path>
--cacheinfo <mode> <object> <path>

指定された情報を直接インデックスに挿入します。下位互換性のために、これら 3 つの引数を 3 つの個別のパラメーターとして指定することもできますが、新しいユーザーは単一パラメーター形式を使用することをお勧めします。

--index-info

stdin からインデックス情報を読み取ります。

--chmod=(+|-)x

更新されたファイルに対して実行権限を設定します。

--[no-]assume-unchanged

このフラグが指定されている場合、パスに記録されたオブジェクト名は更新されません。代わりに、このオプションはパスの「変更されていないと仮定する」ビットを設定/設定解除します。「変更されていないと仮定する」ビットがオンの場合、ユーザーはファイルを変更しないことを約束し、Git はワーキングツリーファイルがインデックスに記録されているものと一致すると仮定できます。ワーキングツリーファイルを変更する場合は、Git に通知するためにビットを設定解除する必要があります。これは、非常に遅い lstat(2) システムコール (例: cifs) を持つファイルシステムで大きなプロジェクトを扱う場合に役立つことがあります。

インデックスでこのファイルを変更する必要がある場合 (たとえば、コミットをマージする場合)、Git は (正常に) 失敗します。したがって、変更されていないと仮定されたファイルがアップストリームで変更された場合は、手動で状況を処理する必要があります。

--really-refresh

--refresh と同様ですが、「変更されていないと仮定する」設定に関係なく、stat 情報を無条件に確認します。

--[no-]skip-worktree

これらのフラグのいずれかが指定されている場合、パスに記録されたオブジェクト名は更新されません。代わりに、これらのオプションはパスの「skip-worktree」ビットを設定および設定解除します。詳細については、以下の「skip-worktree ビット」セクションを参照してください。

--[no-]ignore-skip-worktree-entries

--remove オプションが指定された場合でも、skip-worktree (別名「インデックスのみ」) エントリを削除しません。

--[no-]fsmonitor-valid

これらのフラグのいずれかが指定されている場合、パスに記録されたオブジェクト名は更新されません。代わりに、これらのオプションはパスの「fsmonitor valid」ビットを設定および設定解除します。詳細については、以下の「ファイルシステムモニター」セクションを参照してください。

-g
--again

インデックスエントリが HEAD コミットのエントリと異なるパスに対して、git update-index 自体を実行します。

--unresolve

マージ中に誤ってクリアされた場合、ファイルの 未マージまたは更新が必要な状態を復元します。

--info-only

このフラグに続くすべての <file> 引数に対してオブジェクトデータベースにオブジェクトを作成しないでください。インデックスにオブジェクト ID を挿入するだけです。

--force-remove

ワーキングディレクトリにまだそのようなファイルがある場合でも、インデックスからファイルを削除します。(--remove を暗黙的に示します。)

--replace

デフォルトでは、ファイル path がインデックスに存在する場合、git update-indexpath/file を追加しようとすることを拒否します。同様に、ファイル path/file が存在する場合、ファイル path を追加することはできません。--replace フラグを使用すると、追加されるエントリと競合する既存のエントリは、警告メッセージ付きで自動的に削除されます。

--stdin

コマンドラインからパスのリストを取得する代わりに、標準入力からパスのリストを読み取ります。パスは、デフォルトで LF (つまり、1 行に 1 つのパス) で区切られます。

--verbose

インデックスに追加および削除されるものを報告します。

--index-version <n>

指定されたオンディスク形式バージョンで結果のインデックスを書き出します。サポートされているバージョンは 2、3、および 4 です。現在のデフォルトバージョンは、git add -N などの追加機能が使用されているかどうかによって、2 または 3 です。--verbose を使用すると、このコマンドの前後のインデックスファイルで使用されるバージョンも報告されます。

バージョン 4 は、大規模なリポジトリでインデックスサイズを 30% ~ 50% 削減する単純なパス名圧縮を実行します。これにより、ロード時間が短縮されます。Git は 2012 年 10 月にリリースされたバージョン 1.8.0 以降でサポートしており、2016 年に libgit2 に、2020 年に JGit にサポートが追加されました。このマニュアルページの古いバージョンでは、「比較的新しい」と呼ばれていましたが、最近では成熟したテクノロジーと見なされるべきです。

--show-index-version

オンディスクインデックスファイルで使用されるインデックス形式バージョンを報告します。上記の --index-version を参照してください。

-z

--stdin または --index-info でのみ意味があります。パスは LF の代わりに NUL 文字で区切られます。

--split-index
--no-split-index

分割インデックスモードを有効または無効にします。分割インデックスモードがすでに有効になっていて、--split-index が再度指定されている場合、$GIT_DIR/index のすべての変更が共有インデックスファイルにプッシュバックされます。

これらのオプションは、core.splitIndex 構成変数の値に関係なく有効になります ( git-config[1] を参照)。ただし、構成された値に反する変更が行われた場合は警告が発行されます。構成された値は次回インデックスが読み取られるときに有効になり、オプションの意図された効果が削除されるためです。

--untracked-cache
--no-untracked-cache

追跡されていないキャッシュ機能を有効または無効にします。有効にする前に --test-untracked-cache を使用してください。

これらのオプションは、core.untrackedCache 構成変数の値に関係なく有効になります ( git-config[1] を参照)。ただし、構成された値に反する変更が行われた場合は警告が発行されます。構成された値は次回インデックスが読み取られるときに有効になり、オプションの意図された効果が削除されるためです。

--test-untracked-cache

追跡されていないキャッシュを使用できることを確認するために、ワーキングディレクトリでのみテストを実行します。実際に使用する場合は、後で --untracked-cache または --force-untracked-cache あるいは core.untrackedCache 構成変数を使用して、追跡されていないキャッシュを手動で有効にする必要があります。テストが失敗した場合、終了コードは 1 であり、必要な機能が機能していないことを説明するメッセージが表示されます。それ以外の場合、終了コードは 0 であり、OK と出力されます。

--force-untracked-cache

--untracked-cache と同じです。--untracked-cache--test-untracked-cache を意味していた古いバージョンの Git との下位互換性のために提供されていますが、このオプションは拡張機能を無条件に有効にします。

--fsmonitor
--no-fsmonitor

ファイルシステム監視機能を有効または無効にします。これらのオプションは、core.fsmonitor 設定変数(git-config[1] を参照)の値に関わらず有効になります。ただし、設定された値と異なる変更が行われた場合、警告が出力されます。これは、設定された値が次にインデックスが読み込まれる際に有効になり、オプションの意図された効果がなくなるためです。

--

これ以降の引数をオプションとして解釈しません。

<file>

操作対象のファイル。. で始まるファイルは破棄されることに注意してください。これには、./filedir/./file が含まれます。これを望まない場合は、よりクリーンな名前を使用してください。/ で終わるディレクトリや、// を含むパスにも同様のことが当てはまります。

--REFRESH の使用

--refresh は新しい sha1 ファイルを計算したり、モード/内容の変更に対してインデックスを最新の状態にしたりしません。しかし、実際に行うこと は、ファイルの stat 情報をインデックスと「再照合」することです。これにより、ファイルは変更されていないが stat エントリが古くなっている場合に、インデックスを更新できます。

例えば、git read-tree を実行した後、stat インデックスの詳細を適切なファイルにリンクするためにこれを行うとよいでしょう。

--CACHEINFO または --INFO-ONLY の使用

--cacheinfo は、現在のワーキングディレクトリに存在しないファイルを登録するために使用されます。これは、最小限のチェックアウトマージに役立ちます。

パスにあるファイルにモードと sha1 を持たせたい場合、次のように記述します。

$ git update-index --add --cacheinfo <mode>,<sha1>,<path>

--info-only は、オブジェクトデータベースにファイルを配置せずにファイルを登録するために使用されます。これは、ステータスのみのリポジトリに役立ちます。

--cacheinfo--info-only の両方は、同様に動作します。インデックスは更新されますが、オブジェクトデータベースは更新されません。--cacheinfo は、オブジェクトがデータベースに存在しているが、ファイルがローカルで利用できない場合に役立ちます。--info-only は、ファイルが利用可能であるが、オブジェクトデータベースを更新したくない場合に役立ちます。

--INDEX-INFO の使用

--index-info は、標準入力から複数のエントリ定義をフィードできる、より強力なメカニズムであり、特にスクリプト向けに設計されています。3 つの形式の入力を受け付けることができます。

  1. mode SP type SP sha1 TAB path

    この形式は、git ls-tree の出力をインデックスに格納するためのものです。

  2. mode SP sha1 SP stage TAB path

    この形式は、高次のステージをインデックスファイルに配置するためのものであり、git ls-files --stage の出力と一致します。

  3. mode SP sha1 TAB path

    この形式は、Git コマンドによって生成されなくなりましたが、update-index --index-info によって引き続きサポートされます。

高次のステージエントリをインデックスに配置するには、まずパスに対して mode=0 のエントリをフィードしてパスを削除し、次に必要な入力行を 3 番目の形式でフィードする必要があります。

例えば、このインデックスから開始して

$ git ls-files -s
100644 8a1218a1024a212bb3db30becd860315f9f3ac52 0       frotz

次の入力を --index-info にフィードできます

$ git update-index --index-info
0 0000000000000000000000000000000000000000	frotz
100644 8a1218a1024a212bb3db30becd860315f9f3ac52 1	frotz
100755 8a1218a1024a212bb3db30becd860315f9f3ac52 2	frotz

入力の最初の行は、パスを削除するためにモードとして 0 をフィードします。SHA-1 は、適切にフォーマットされていれば重要ではありません。次に、2 番目と 3 番目の行は、そのパスのステージ 1 とステージ 2 のエントリをフィードします。上記の後、最終的に次のようになります。

$ git ls-files -s
100644 8a1218a1024a212bb3db30becd860315f9f3ac52 1	frotz
100755 8a1218a1024a212bb3db30becd860315f9f3ac52 2	frotz

「変更なしと仮定」ビットの使用

Git の多くの操作は、ファイルシステムが効率的な lstat(2) 実装を持っていることに依存しています。これにより、ワーキングツリーファイルの st_mtime 情報を安価にチェックして、ファイルの内容がインデックスファイルに記録されたバージョンから変更されたかどうかを確認できます。残念ながら、一部のファイルシステムは効率の悪い lstat(2) を持っています。ファイルシステムがそのいずれかである場合は、変更していないパスに「変更なしと仮定」ビットを設定して、Git がこのチェックを行わないようにすることができます。パスにこのビットを設定しても、Git がファイルの内容をチェックして変更されたかどうかを確認するわけではないことに注意してください。Git は、チェックを省略し、変更されていない と仮定します。ワーキングツリーファイルに変更を加えた場合は、変更する前または後に「変更なしと仮定」ビットを削除して、変更について Git に明示的に通知する必要があります。

「変更なしと仮定」ビットを設定するには、--assume-unchanged オプションを使用します。設定を解除するには、--no-assume-unchanged を使用します。「変更なしと仮定」ビットが設定されているファイルを確認するには、git ls-files -v を使用します(git-ls-files[1] を参照)。

コマンドは、core.ignorestat 設定変数を参照します。これが true の場合、git update-index paths... で更新されたパスと、インデックスとワーキングツリーの両方を更新する他の Git コマンド(例:git apply --indexgit checkout-index -ugit read-tree -u)で更新されたパスは、自動的に「変更なしと仮定」としてマークされます。「変更なしと仮定」ビットは、git update-index --refresh がワーキングツリーファイルがインデックスと一致することを検出した場合に設定されないことに注意してください(それらを「変更なしと仮定」としてマークする場合は、git update-index --really-refresh を使用します)。

ユーザーは、変更なしと仮定ビットとスキップワーキングツリービットを混同することがあります。違いの説明については、以下の「スキップワーキングツリービット」セクションの最後の段落を参照してください。

既にチェックアウトされているファイルのみを更新およびリフレッシュするには

$ git checkout-index -n -f -a && git update-index --ignore-missing --refresh
core.ignorestat が設定された非効率的なファイルシステムの場合
$ git update-index --really-refresh              (1)
$ git update-index --no-assume-unchanged foo.c   (2)
$ git diff --name-only                           (3)
$ edit foo.c
$ git diff --name-only                           (4)
M foo.c
$ git update-index foo.c                         (5)
$ git diff --name-only                           (6)
$ edit foo.c
$ git diff --name-only                           (7)
$ git update-index --no-assume-unchanged foo.c   (8)
$ git diff --name-only                           (9)
M foo.c
  1. lstat(2) を強制して、インデックスと一致するパスに対して「変更なしと仮定」ビットを設定します。

  2. 編集するパスをマークします。

  3. これは lstat(2) を実行し、インデックスがパスと一致することを見つけます。

  4. これは lstat(2) を実行し、インデックスがパスと一致しない ことを見つけます。

  5. 新しいバージョンをインデックスに登録すると、「変更なしと仮定」ビットが設定されます。

  6. そして、変更されていないと仮定されます。

  7. 編集した後でも。

  8. 後から変更を通知できます。

  9. これで、lstat(2) でチェックし、変更されたことを検出します。

スキップワーキングツリービット

スキップワーキングツリービットは、(長い)1 つの文で定義できます。可能な限り、ワーキングディレクトリへのファイルの書き込みを回避するように Git に指示し、ワーキングディレクトリにファイルが存在しない場合は、ファイルを変更されていないものとして扱います。

すべての Git コマンドがこのビットに注意を払うわけではなく、一部は部分的にのみサポートしていることに注意してください。

スキップワーキングツリービットに関連する update-index フラグと read-tree 機能は、git-sparse-checkout[1] コマンドの導入より前に存在していました。これにより、スキップワーキングツリービットの設定と処理がはるかに簡単になります。リポジトリ内のファイルのサブセットのみを処理するようにワーキングツリーを削減する場合は、低レベルの update-index および read-tree プリミティブよりも、git-sparse-checkout[1] を使用することを強くお勧めします。

スキップワーキングツリービットの主な目的は、スパースチェックアウトを有効にすることです。つまり、パスのサブセットのみが存在するワーキングディレクトリを持つことです。スキップワーキングツリービットが設定されている場合、Git コマンド(switchpullmerge など)はこれらのファイルの書き込みを回避します。ただし、これらのコマンドは、マージまたはリベース中の競合など、重要な場合には、これらのファイルを書き込むことがあります。Git コマンドは、このようなファイルがないことを意図的な削除として扱うことも回避します。たとえば、git add -u はこれらのファイルの削除をステージングせず、git commit -a もそれらを削除するコミットを作成しません。

このビットは変更なしと仮定ビットに似ていますが、その目的は異なります。変更なしと仮定ビットは、ファイルをワーキングツリーに残し、Git が変更のチェックを省略して、ファイルが変更されていないと仮定するためのものです(ただし、ファイルを stat しなくても変更されたことを特定できる場合は、変更を記録できます)。スキップワーキングツリーは、ファイルの不在を無視するように Git に指示し、ワーキングディレクトリの多くを通常更新するコマンド(checkoutswitchpull など)で可能な場合は更新を回避し、不在がコミットに記録されないようにします。スパースチェックアウト(git sparse-checkout で設定するか、core.sparseCheckout を true に設定することで設定)では、ファイルがインデックスでスキップワーキングツリーとしてマークされているが、ワーキングツリーに存在する場合は、Git はそのファイルのスキップワーキングツリービットをクリアすることに注意してください。

分割インデックス

このモードは、非常に大きなインデックスを持つリポジトリ向けに設計されており、これらのインデックスを繰り返し書き込むのにかかる時間を短縮することを目的としています。

このモードでは、インデックスは 2 つのファイル、$GIT_DIR/index および $GIT_DIR/sharedindex.<SHA-1> に分割されます。変更は $GIT_DIR/index(分割インデックス)に蓄積され、共有インデックスファイルにはすべてのインデックスエントリが含まれており、変更されません。

分割インデックスのすべての変更は、分割インデックスのエントリ数が splitIndex.maxPercentChange 設定変数で指定されたレベルに達すると、共有インデックスファイルにプッシュバックされます(git-config[1] を参照)。

新しい共有インデックスファイルが作成されるたびに、古い共有インデックスファイルの変更時間が splitIndex.sharedIndexExpire 設定変数で指定された時間よりも古い場合、それらのファイルは削除されます(git-config[1] を参照)。

まだ使用されている共有インデックスファイルの削除を回避するために、共有インデックスファイルに基づいて新しい分割インデックスが作成または読み取りされるたびに、変更時間が現在の時間に更新されます。

追跡されていないキャッシュ

このキャッシュは、git status など、追跡されていないファイルの特定を伴うコマンドを高速化することを目的としています。

この機能は、ワーキングツリーディレクトリの mtime を記録し、mtime が変更されていないディレクトリ内のファイルに対するディレクトリの読み取りと stat 呼び出しを省略することによって機能します。これが機能するためには、基盤となるオペレーティングシステムとファイルシステムが、ディレクトリ内のファイルが追加、変更、または削除された場合に、ディレクトリの st_mtime フィールドを変更する必要があります。

--test-untracked-cache オプションを使用して、ファイルシステムがそれをサポートしているかどうかをテストできます。--untracked-cache オプションは、以前のバージョンの Git でそのテストを暗黙的に実行していましたが、そうではなくなりました。

この機能を有効(または無効)にする場合は、各リポジトリで git update-index--untracked-cache オプションを使用するよりも、core.untrackedCache 設定変数(git-config[1] を参照)を使用する方が簡単です。特に、使用するすべてのリポジトリでこれを行う場合は、$HOME/.gitconfig で設定変数を true(または false)に 1 回設定するだけで、触れるすべてのリポジトリに影響を与えることができます。

core.untrackedCache 設定変数が変更されると、コマンドがインデックスを次に読み込むときに、追跡されていないキャッシュがインデックスに追加または削除されます。一方、--[no-|force-]untracked-cache が使用されると、追跡されていないキャッシュはすぐにインデックスに追加または削除されます。

2.17 より前は、追跡されていないキャッシュには、ディレクトリを別のディレクトリへのシンボリックリンクで置き換えると、Git によって追跡されるファイルが追跡されていないものとして誤って表示される可能性があるバグがありました。git.git への「status: add a failing test showing a core.untrackedCache bug」コミットを参照してください。その回避策は(そして、これは将来の他の未発見のバグにも有効になる可能性があります)

$ git -c core.untrackedCache=false status

このバグは、追跡されていないキャッシュの内部構造に関する限り、ディレクトリをファイルで置き換える非シンボリックリンクの場合にも影響を与えることが示されていますが、これにより「git status」の出力が間違って表示されるケースは報告されていません。

2.17 より前のバージョンの Git によって書き込まれた既存のインデックスが、もう存在しないディレクトリを参照し、その結果、「git status」で多くの「ディレクトリを開けませんでした」という警告が出力される可能性もあります。これらは、以前は黙って破棄されていた既存の問題に対する新しい警告です。

上記で説明したバグと同様に、解決策は、一時的にcore.untrackedCache=falseを指定して「git status」を実行し、残っている不正なデータをフラッシュすることです。

ファイルシステムモニター

この機能は、大規模なワーキングディレクトリを持つリポジトリでのgit操作を高速化することを目的としています。

これにより、gitは、どのファイルが変更されたかを通知できるファイルシステムモニター(git-fsmonitor--daemon[1]およびgithooks[5]の「fsmonitor-watchman」セクションを参照)と連携できます。これにより、gitは、変更されたファイルを見つけるためにすべてのファイルのlstat()を実行する必要がなくなります。

追跡対象外キャッシュと組み合わせて使用すると、ワーキングディレクトリ全体をスキャンして新しいファイルを探すコストを回避できるため、パフォーマンスをさらに向上させることができます。

この機能を有効(または無効)にする場合は、特に使用するすべてのリポジトリで有効にしたい場合は、core.fsmonitor設定変数(git-config[1]を参照)を使用する方が、各リポジトリでgit update-index--fsmonitorオプションを使用するよりも簡単です。$HOME/.gitconfigに設定変数を1回設定するだけで、触れるすべてのリポジトリに影響を与えることができるからです。

core.fsmonitor設定変数が変更されると、次にコマンドがインデックスを読み取るときに、ファイルシステムモニターがインデックスに追加または削除されます。--[no-]fsmonitorを使用すると、ファイルシステムモニターはインデックスにすぐに追加または削除されます。

設定

このコマンドは、core.filemode設定変数を尊重します。リポジトリが実行可能ビットが信頼できないファイルシステム上にある場合は、これをfalseに設定する必要があります(git-config[1]を参照)。これにより、実行可能ビットのみが異なる場合、コマンドはインデックスに記録されているファイルモードとファイルシステムのファイルモードの違いを無視します。このような不運なファイルシステムでは、git update-index --chmod=を使用する必要があるかもしれません。

同様に、core.symlinks設定変数がfalseに設定されている場合(git-config[1]を参照)、シンボリックリンクはプレーンファイルとしてチェックアウトされ、このコマンドは記録されたファイルモードをシンボリックリンクから通常のファイルに変更しません。

このコマンドは、core.ignorestat設定変数を確認します。上記の「変更されていないと仮定」ビットの使用のセクションを参照してください。

このコマンドは、core.trustctime設定変数も確認します。inode変更時間がGitの外部(ファイルシステムクローラーやバックアップシステムは、処理されたファイルをマークするためにctimeを使用します)によって定期的に変更される場合に役立ちます(git-config[1]を参照)。

追跡対象外キャッシュ拡張機能は、core.untrackedCache設定変数で有効にできます(git-config[1]を参照)。

ユーザーは、追跡対象のファイルの変更をGitに無視させるために、assume-unchangedおよびskip-worktreeビットを使用しようとすることがよくあります。Gitは、特定の操作を実行するときにワーキングツリーのファイルをインデックスと照合する可能性があるため、これは期待どおりには機能しません。一般的に、Gitは追跡対象のファイルの変更を無視する方法を提供していないため、代替の解決策が推奨されます。

たとえば、変更したいファイルが何らかの設定ファイルである場合、リポジトリには、無視された名前にコピーして変更できるサンプル設定ファイルを含めることができます。リポジトリには、サンプルファイルをテンプレートとして扱い、自動的に変更およびコピーするスクリプトを含めることもできます。

GIT

git[1]スイートの一部

scroll-to-top