# git-update-index
> 原文: [https://git-scm.com/docs/git-update-index](https://git-scm.com/docs/git-update-index)
## 名稱
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-]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>]
[--verbose]
[--] [<file>…?]
```
## 描述
修改索引或目錄高速緩存。提到的每個文件都被更新到索引中,并且任何_未合并_或_需要更新_狀態被清除。
另請參閱 [git-add [1]](https://git-scm.com/docs/git-add) ,以便以更加用戶友好的方式對索引執行一些最常見的操作。
_git update-index_ 處理文件的方式可以使用各種選項進行修改:
## OPTIONS
```
--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>
```
直接將指定的信息插入索引。為了向后兼容,您還可以將這三個參數作為三個單獨的參數提供,但鼓勵新用戶使用單參數表單。
```
--index-info
```
從stdin讀取索引信息。
```
--chmod=(+|-)x
```
設置更新文件的執行權限。
```
--[no-]assume-unchanged
```
指定此標志時,不會更新為路徑記錄的對象名稱。相反,此選項設置/取消設置路徑的“假定未更改”位。當“假設未更改”位打開時,用戶承諾不更改文件并允許Git假定工作樹文件與索引中記錄的文件匹配。如果要更改工作樹文件,則需要取消設置該位以告知Git。當在具有非常慢的lstat(2)系統調用(例如cifs)的文件系統上處理大項目時,這有時是有用的。
如果需要在索引中修改此文件,Git將失敗(優雅地),例如合并時提交;因此,如果上游更改了假定未跟蹤文件,則需要手動處理該情況。
```
--really-refresh
```
與`--refresh`類似,但無條件地檢查統計信息,而不考慮“假定未更改”設置。
```
--[no-]skip-worktree
```
指定其中一個標志時,不會更新為路徑記錄的對象名稱。相反,這些選項設置和取消設置路徑的“skip-worktree”位。有關詳細信息,請參閱下面的“跳過工作樹位”部分。
```
--[no-]fsmonitor-valid
```
指定其中一個標志時,不會更新為路徑記錄的對象名稱。相反,這些選項設置和取消設置路徑的“fsmonitor valid”位。有關詳細信息,請參閱下面的“文件系統監視器”部分
```
-g
```
```
--again
```
在索引條目與`HEAD`提交的索引條目不同的路徑上運行 _git update-index_ 本身。
```
--unresolve
```
如果意外清除,則恢復_未合并_或_需要在合并期間更新文件的_狀態。
```
--info-only
```
不要在對象數據庫中為所有< file>創建對象跟隨這面旗幟的論據;只需將其對象ID插入索引即可。
```
--force-remove
```
即使工作目錄仍有這樣的文件,也要從索引中刪除該文件。 (意味著 - 刪除。)
```
--replace
```
默認情況下,當索引中存在文件`path`時, _git update-index_ 拒絕添加`path/file`的嘗試。同樣,如果存在文件`path/file`,則無法添加文件`path`。使用--replace標志,將自動刪除與添加的條目沖突的現有條目以及警告消息。
```
--stdin
```
而不是從命令行獲取路徑列表,從標準輸入中讀取路徑列表。默認情況下,路徑由LF(即每行一個路徑)分隔。
```
--verbose
```
報告從索引中添加和刪除的內容。
```
--index-version <n>
```
將結果索引寫入指定的磁盤格式版本。支持的版本為2,3和4.當前默認版本為2或3,具體取決于是否使用了額外功能,例如`git add -N`。
版本4執行簡單的路徑名壓縮,在大型存儲庫上將索引大小減少30%-50%,從而加快了加載時間。版本4相對年輕(2012年10月首次發布于1.8.0)。其他Git實現(如JGit和libgit2)可能還不支持它。
```
-z
```
僅對`--stdin`或`--index-info`有意義;路徑用NUL字符而不是LF分隔。
```
--split-index
```
```
--no-split-index
```
啟用或禁用拆分索引模式。如果已啟用拆分索引模式并再次給出`--split-index`,則$ GIT_DIR / index中的所有更改都將推回到共享索引文件。
無論`core.splitIndex`配置變量的值如何,這些選項都會生效(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。但是當更改違反配置值時會發出警告,因為配置的值將在下次讀取索引時生效,這將消除該選項的預期效果。
```
--untracked-cache
```
```
--no-untracked-cache
```
啟用或禁用未跟蹤的緩存功能。請在啟用之前使用`--test-untracked-cache`。
無論`core.untrackedCache`配置變量的值如何,這些選項都會生效(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。但是當更改違反配置值時會發出警告,因為配置的值將在下次讀取索引時生效,這將消除該選項的預期效果。
```
--test-untracked-cache
```
僅對工作目錄執行測試以確保可以使用未跟蹤的緩存。如果您真的想使用它,則必須使用`--untracked-cache`或`--force-untracked-cache`或`core.untrackedCache`配置變量手動啟用未跟蹤的緩存。如果測試失敗,則退出代碼為1,并且消息說明根據需要不起作用的內容,否則退出代碼為0并打印OK。
```
--force-untracked-cache
```
與`--untracked-cache`相同。提供與舊版Git的向后兼容性,其中`--untracked-cache`曾暗示`--test-untracked-cache`,但此選項將無條件地啟用擴展。
```
--fsmonitor
```
```
--no-fsmonitor
```
啟用或禁用文件系統監視器功能。無論`core.fsmonitor`配置變量的值如何,這些選項都會生效(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。但是當更改違反配置值時會發出警告,因為配置的值將在下次讀取索引時生效,這將消除該選項的預期效果。
```
--
```
不要將任何更多的參數解釋為選項。
```
<file>
```
要采取行動的文件。請注意以_開頭的文件。_ 被丟棄。這包括`./file`和`dir/./file`。如果您不想這樣,那么使用更干凈的名稱。結束 _/_ 的目錄和 _//_ 的路徑也是如此
## 使用--REFRESH
`--refresh`不計算新的sha1文件或使模式/內容更改的索引更新。但是做的是將文件的統計信息與索引“重新匹配”,以便您可以刷新尚未更改的文件的索引但是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`是一種更強大的機制,允許您從標準輸入中提供多個條目定義,并專門為腳本設計。它可以采用三種格式的輸入:
1. 模式SP類型SP sha1 TAB路徑
這種格式是將`git ls-tree`輸出填充到索引中。
2. 模式SP sha1 SP階段TAB路徑
這種格式是將更高階的階段放入索引文件中,并匹配 _git ls-files --stage_ 輸出。
3. 模式SP sha1 TAB路徑
任何Git命令都不再生成此格式,但`update-index --index-info`將繼續支持此格式。
要為索引放置更高的階段條目,首先應通過為路徑提供mode = 0條目,然后以第三種格式提供必要的輸入行來刪除路徑。
例如,從這個索引開始:
```
$ 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無關緊要。然后第二行和第三行為該路徑提供階段1和階段2條目。在上述之后,我們最終會得到:
```
$ git ls-files -s
100644 8a1218a1024a212bb3db30becd860315f9f3ac52 1 frotz
100755 8a1218a1024a212bb3db30becd860315f9f3ac52 2 frotz
```
## 使用“ASSUME UNCHANGED”BIT
Git中的許多操作依賴于您的文件系統以實現高效的`lstat(2)`實現,因此可以便宜地檢查工作樹文件的`st_mtime`信息,以查看文件內容是否已從索引文件中記錄的版本更改。不幸的是,一些文件系統效率低`lstat(2)`。如果您的文件系統是其中之一,則可以將“假設未更改”位設置為未更改的路徑,以使Git不執行此檢查。請注意,在路徑上設置此位并不意味著Git將檢查文件的內容以查看它是否已更改 - 它使Git省略任何檢查并假設它已更改**而不是**。當您對工作樹文件進行更改時,您必須通過在修改它們之前或之后刪除“假定未更改”位來明確告知Git。
要設置“假定未更改”位,請使用`--assume-unchanged`選項。要取消設置,請使用`--no-assume-unchanged`。要查看哪些文件設置了“假設未更改”,請使用`git ls-files -v`(參見 [git-ls-files [1]](https://git-scm.com/docs/git-ls-files) )。
該命令查看`core.ignorestat`配置變量。如果是這樣,使用`git update-index paths...`更新路徑,并使用更新索引和工作樹的其他Git命令更新路徑(例如 _git apply --index_ , _git checkout-index -u_ 和 _git read-tree -u_ )自動標記為“假設不變”。注意,如果`git update-index --refresh`發現工作樹文件與索引匹配,則“假定未更改”位為**而不是**設置(如果要將它們標記為“假設未更改”,請使用`git update-index --really-refresh`)。
## 例子
要僅更新和刷新已檢出的文件:
```
$ git checkout-index -n -f -a && git update-index --ignore-missing --refresh
```
```
On an inefficient filesystem with core.ignorestat set
```
```
$ 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)并發現它已被更改。
## SKIP-WORKTREE BIT
Skip-worktree位可以在一個(長)句子中定義:當讀取條目時,如果它被標記為skip-worktree,那么Git假裝其工作目錄版本是最新的并且改為讀取索引版本。
詳細說明,“閱讀”意味著檢查文件是否存在,讀取文件屬性或文件內容。工作目錄版本可能存在或不存在。如果存在,其內容可能與索引版本匹配。寫入不受此位影響,內容安全仍然是第一優先。請注意,Git _可以_更新工作目錄文件,標記為skip-worktree,如果安全的話(即工作目錄版本與索引版本匹配)
雖然這個位看起來類似于假設未改變的位,但它的目標與假設未改變的位不同。當兩者都設置時,Skip-worktree也優先于假定未更改的位。
## 分裂指數
此模式適用于具有非常大索引的存儲庫,旨在減少重復編寫這些索引所需的時間。
在此模式下,索引分為兩個文件:$ GIT_DIR / index和$ GIT_DIR / sharedindex。< SHA-1>。更改將在$ GIT_DIR / index(拆分索引)中累積,而共享索引文件包含所有索引條目并保持不變。
當拆分索引中的條目數達到splitIndex.maxPercentChange配置變量指定的級別時,拆分索引中的所有更改都會被推回到共享索引文件中(請參閱 [git-config [1]](https://git-scm.com/docs/git-config) )。
每次創建新的共享索引文件時,如果舊的共享索引文件的修改時間早于splitIndex.sharedIndexExpire配置變量指定的值,則刪除舊的共享索引文件(請參閱 [git-config [1]](https://git-scm.com/docs/git-config) )。
為了避免刪除仍在使用的共享索引文件,每次創建或讀取基于共享索引文件的新拆分索引時,其修改時間將更新為當前時間。
## UNTRACKED CACHE
此緩存旨在加速涉及確定未跟蹤文件(例如`git status`)的命令。
此功能的工作原理是記錄工作樹目錄的mtime,然后忽略對mtime未更改的目錄中的文件的讀取目錄和stat調用。為此,如果添加,修改或刪除目錄中的文件,則底層操作系統和文件系統必須更改目錄的`st_mtime`字段。
您可以使用`--test-untracked-cache`選項測試文件系統是否支持該文件系統。 `--untracked-cache`選項用于在舊版本的Git中隱式執行該測試,但情況已不再如此。
如果要啟用(或禁用)此功能,則使用`core.untrackedCache`配置變量(參見 [git-config [1]](https://git-scm.com/docs/git-config) )比使用`git update-index`選項更容易使用`git update-index`每個存儲庫,特別是如果您想在所使用的所有存儲庫中執行此操作,因為您可以在`$HOME/.gitconfig`中將配置變量設置為`true`(或`false`)一次,并使其影響您觸摸的所有存儲庫。
更改`core.untrackedCache`配置變量時,下次命令讀取索引時,會將未跟蹤的高速緩存添加到索引中或從索引中刪除;當使用`--[no-|force-]untracked-cache`時,未跟蹤的緩存會立即添加到索引中或從索引中刪除。
在2.17之前,未跟蹤的緩存有一個錯誤,將帶有符號鏈接的目錄替換到另一個目錄可能會導致錯誤地將git跟蹤的文件顯示為未跟蹤。請參閱“狀態:添加一個顯示core.untrackedCache錯誤的失敗測試”提交到git.git。解決方法是(這可能適用于未來其他未發現的錯誤):
```
$ git -c core.untrackedCache=false status
```
當涉及到未跟蹤緩存的內部結構時,此錯誤也被證明會影響用文件替換目錄的非符號鏈接情況,但是沒有報告導致錯誤“git status”輸出的情況。
還有一些情況,在2.17之前由git版本編寫的現有索引將引用不再存在的目錄,可能導致許多“無法打開目錄”警告打印在“git status”上。這些是以前默默丟棄的現有問題的新警告。
與上述錯誤一樣,解決方案是一次性使用`core.untrackedCache=false`執行“git status”以清除剩余的壞數據。
## 文件系統監控
此功能旨在加速具有大型工作目錄的repos的git操作。
它使git能夠與文件系統監視器一起工作(參見 [githooks [5]](https://git-scm.com/docs/githooks) 的“fsmonitor-watchman”部分),它可以告知它已經修改了哪些文件。這使得git可以避免必須lstat()每個文件來查找修改過的文件。
與未跟蹤的緩存一起使用時,它可以通過避免掃描整個工作目錄以查找新文件的成本來進一步提高性能。
如果要啟用(或禁用)此功能,則使用`core.fsmonitor`配置變量(參見 [git-config [1]](https://git-scm.com/docs/git-config) )比使用`git update-index`選項更容易使用`git update-index`每個存儲庫,特別是如果您想在所使用的所有存儲庫中執行此操作,因為您可以在`$HOME/.gitconfig`中設置一次配置變量,并使其影響您觸摸的所有存儲庫。
更改`core.fsmonitor`配置變量時,下次命令讀取索引時,會在索引中添加或刪除文件系統監視器。使用`--[no-]fsmonitor`時,會立即將文件系統監視器添加到索引中或從索引中刪除。
## 組態
該命令用于表示`core.filemode`配置變量。如果您的存儲庫位于可執行位不可靠的文件系統上,則應將其設置為 _false_ (請參閱 [git-config [1]](https://git-scm.com/docs/git-config) )。這會導致命令忽略文件系統中索引和文件模式中記錄的文件模式的差異(如果它們僅在可執行位上不同)。在這樣一個不幸的文件系統上,您可能需要使用 _git update-index --chmod =_ 。
很相似,如果`core.symlinks`配置變量設置為 _false_ (參見 [git-config [1]](https://git-scm.com/docs/git-config) ),則符號鏈接被檢出為普通文件,并且此命令不會修改從符號鏈接到常規文件的記錄文件模式。
該命令查看`core.ignorestat`配置變量。參見_使用上面的“假設未改變”位_部分。
該命令還會查看`core.trustctime`配置變量。當通過Git之外的某些東西定期修改inode更改時間(文件系統爬蟲和備份系統使用ctime標記處理的文件)時,它會很有用(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。
可以通過`core.untrackedCache`配置變量啟用未跟蹤的高速緩存擴展(參見 [git-config [1]](https://git-scm.com/docs/git-config) )。
## 也可以看看
[git-config [1]](https://git-scm.com/docs/git-config) , [git-add [1]](https://git-scm.com/docs/git-add) , [git-ls-files [1]](https://git-scm.com/docs/git-ls-files)
## GIT
部分 [git [1]](https://git-scm.com/docs/git) 套件
- git
- git-config
- git-help
- git-init
- git-clone
- git-add
- git-status
- git-diff
- git-commit
- git-reset
- git-rm
- git-mv
- git-branch
- git-checkout
- git-merge
- git-mergetool
- git-log
- git-stash
- git-tag
- git-worktree
- git-fetch
- git-pull
- git-push
- git-remote
- git-submodule
- git-show
- git-log
- git-shortlog
- git-describe
- git-apply
- git-cherry-pick
- git-rebase
- git-revert
- git-bisect
- git-blame
- git-grep
- gitattributes
- giteveryday
- gitglossary
- githooks
- gitignore
- gitmodules
- gitrevisions
- gittutorial
- gitworkflows
- git-am
- git-format-patch
- git-send-email
- git-request-pull
- git-svn
- git-fast-import
- git-clean
- git-gc
- git-fsck
- git-reflog
- git-filter-branch
- git-instaweb
- git-archive
- git-bundle
- git-daemon
- git-update-server-info
- git-cat-file
- git-check-ignore
- git-checkout-index
- git-commit-tree
- git-count-objects
- git-diff-index
- git-for-each-ref
- git-hash-object
- git-ls-files
- git-merge-base
- git-read-tree
- git-rev-list
- git-rev-parse
- git-show-ref
- git-symbolic-ref
- git-update-index
- git-update-ref
- git-verify-pack
- git-write-tree