Git
简体中文 ▾ Topics ▾ Latest version ▾ git-update-index last updated in 2.44.0

名称

git-update-index - 将工作区中的文件内容注册到索引中

概述

git update-index
	     [--add] [--remove | --force-remove] [--replace]
	     [--refresh] [-q] [--unmerged] [--ignore-missing]
	     [(--cacheinfo <模式>,<对象>,<文件>)…​]
	     [--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>]
	     [--verbose]
	     [--] [<文件>…​]

描述

修改索引。提到的每个文件都会更新到索引中,任何 “未合并” 或 “需要更新” 的状态都会被清除。

参见 git-add[1],以获取更友好的索引操作方法。

git update-index 处理文件的方式可以通过各种选项来修改:

选项

--add

If a specified file isn’t in the index already then it’s added. Default behaviour is to ignore new files.

--remove

If a specified file is in the index but is missing then it’s removed. Default behavior is to ignore removed files.

--refresh

查看当前索引,并通过检查 stat() 信息查看是否需要合并或更新。

-q

Quiet. If --refresh finds that the index needs an update, the default behavior is to error out. This option makes git update-index continue anyway.

--ignore-submodules

Do not try to update submodules. This option is only respected when passed before --refresh.

--unmerged

If --refresh finds unmerged changes in the index, the default behavior is to error out. This option makes git update-index continue anyway.

--ignore-missing

在 --refresh 过程中忽略丢失的文件

--cacheinfo <模式>,<对象>,<路径>
--cacheinfo <模式> <对象> <路径>

Directly insert the specified info into the index. For backward compatibility, you can also give these three arguments as three separate parameters, but new users are encouraged to use a single-parameter form.

--index-info

从标准输入流读取索引信息。

--chmod=(+|-)x

设置更新文件的执行权限。

--[no-]assume-unchanged

When this flag is specified, the object names recorded for the paths are not updated. Instead, this option sets/unsets the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, the user promises not to change the file and allows Git to assume that the working tree file matches what is recorded in the index. If you want to change the working tree file, you need to unset the bit to tell Git. This is sometimes helpful when working with a big project on a filesystem that has a very slow lstat(2) system call (e.g. cifs).

如果 Git 需要在索引中修改该文件,例如在合并提交时,Git 会(优雅地)失败;因此,如果假定未跟踪的文件在上游被修改,你需要手动处理这种情况。

--really-refresh

类似于 --refresh,但无条件检查统计信息,不考虑 “假设不变” 设置。

--[no-]skip-worktree

如果指定了这些标志之一,路径记录的对象名称将不会更新。相反,这些选项会设置或取消路径的 “跳过工作树” 位。更多信息,请参阅下文 “跳过工作树位” 部分。

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

即使指定了 --remove 选项,也不会删除跳过工作区(又称 “仅索引” )条目。

--[no-]fsmonitor-valid

如果指定了这些标志之一,则不会更新路径记录的对象名称。相反,这些选项会设置或取消路径的 "fsmonitor valid" 位。更多信息,请参阅下文 “文件系统监视器” 部分。

-g
--again

在索引项与 HEAD 提交不同的路径上运行 git update-index

--unresolve

在合并过程中,如果意外清除了文件的 “未合并” 或 “需要更新” 状态,则恢复该状态。

--info-only

不在对象数据库中为所有使用此标记的 <文件> 参数创建对象;只将其对象 ID 插入索引。

--force-remove

从索引中删除文件,即使工作目录中仍有该文件。(意味着 --remove 。)

--replace

By default, when a file path exists in the index, git update-index refuses an attempt to add path/file. Similarly if a file path/file exists, a file path cannot be added. With --replace flag, existing entries that conflict with the entry being added are automatically removed with warning messages.

--stdin

Instead of taking a list of paths from the command line, read a list of paths from the standard input. Paths are separated by LF (i.e. one path per line) by default.

--verbose

报告索引中添加和删除的内容。

--index-version <n>

Write the resulting index out in the named on-disk format version. Supported versions are 2, 3, and 4. The current default version is 2 or 3, depending on whether extra features are used, such as git add -N. With --verbose, also report the version the index file uses before and after this command.

Version 4 performs a simple pathname compression that reduces index size by 30%-50% on large repositories, which results in faster load time. Git supports it since version 1.8.0, released in October 2012, and support for it was added to libgit2 in 2016 and to JGit in 2020. Older versions of this manual page called it "relatively young", but it should be considered mature technology these days.

--show-index-version

Report the index format version used by the on-disk index file. See --index-version above.

-z

只有在使用 --stdin--index-info 时才有意义;路径用 NUL 字符分隔,而不用 LF。

--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-cachecore.untrackedCache 配置变量手动启用它。如果测试失败,则退出代码为 1,并根据需要给出一条信息,说明测试失败的原因,否则退出代码为 0,并打印 OK。

--force-untracked-cache

--untracked-cache 相同。提供该选项是为了向后兼容旧版本的 Git,在旧版本中,--untracked-cache 意味着 --test-untracked-cache ,但该选项将无条件启用扩展。

--fsmonitor
--no-fsmonitor

启用或禁用文件系统监视器功能。无论 core.fsmonitor 配置变量的值是多少,这些选项都会生效(参见 git-config[1])。但如果更改与配置值相反,则会发出警告,因为配置值会在下次读取索引时生效,从而消除选项的预期效果。

--

不将之后的参数解释为选项。

<文件>

Files to act on. Note that files beginning with . are discarded. This includes ./file and dir/./file. If you don’t want this, then use cleaner names. The same applies to directories ending / and paths with //

使用 --REFRESH

--refresh 选项不会计算新的 sha1 文件,也不会为模式/内容更改更新索引。但是,它要做的是将文件的统计信息与索引 “重新匹配”,以便您可以刷新未更改但统计条目已过期的文件的索引。

例如,您需要在执行 git read-tree 后执行此操作,以便将统计索引详情与适当的文件联系起来。

使用 --CACHEINFO 或 --INFO-ONLY

--cacheinfo is used to register a file that is not in the current working directory. This is useful for minimum-checkout merging.

假设路径下有一个文件,带有模式和 sha1,例如:

$ git update-index --add --cacheinfo <模式>,<sha1>,<路径>

--info-only is used to register files without placing them in the object database. This is useful for status-only repositories.

Both --cacheinfo and --info-only behave similarly: the index is updated but the object database isn’t. --cacheinfo is useful when the object is in the database but the file isn’t available locally. --info-only is useful when the file is available, but you do not wish to update the object database.

使用 --INDEX-INFO

--index-info is a more powerful mechanism that lets you feed multiple entry definitions from the standard input, and designed specifically for scripts. It can take inputs of three formats:

  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 将继续支持这种格式。

若要在索引中输入更高一级的条目,应首先删除路径,为路径输入模式 =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

The first line of the input feeds 0 as the mode to remove the path; the SHA-1 does not matter as long as it is well formatted. Then the second and third line feeds stage 1 and stage 2 entries for that path. After the above, we would end up with this:

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

使用 '假设不变' 位

Many operations in Git depend on your filesystem to have an efficient lstat(2) implementation, so that st_mtime information for working tree files can be cheaply checked to see if the file contents have changed from the version recorded in the index file. Unfortunately, some filesystems have inefficient lstat(2). If your filesystem is one of them, you can set "assume unchanged" bit to paths you have not changed to cause Git not to do this check. Note that setting this bit on a path does not mean Git will check the contents of the file to see if it has changed — it makes Git to omit any checking and assume it has not changed. When you make changes to working tree files, you have to explicitly tell Git about it by dropping "assume unchanged" bit, either before or after you modify them.

In order to set "assume unchanged" bit, use --assume-unchanged option. To unset, use --no-assume-unchanged. To see which files have the "assume unchanged" bit set, use git ls-files -v (see git-ls-files[1]).

The command looks at core.ignorestat configuration variable. When this is true, paths updated with git update-index paths... and paths updated with other Git commands that update both index and working tree (e.g. git apply --index, git checkout-index -u, and git read-tree -u) are automatically marked as "assume unchanged". Note that "assume unchanged" bit is not set if git update-index --refresh finds the working tree file matches the index (use git update-index --really-refresh if you want to mark them as "assume unchanged").

Sometimes users confuse the assume-unchanged bit with the skip-worktree bit. See the final paragraph in the "Skip-worktree bit" section below for an explanation of the differences.

实例

只更新和刷新已签出的文件:

$ 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) 进行检查,发现它已被更改。

跳过工作区位

跳过工作区位可以用一句(长)话来定义:告诉 Git 在合理的情况下避免将文件写入工作目录,当文件不在工作目录中时,将其视为不变文件。

请注意,并非所有的 Git 命令都会关注这一点,有些命令仅部分支持这一点。

The update-index flags and the read-tree capabilities relating to the skip-worktree bit predated the introduction of the git-sparse-checkout[1] command, which provides a much easier way to configure and handle the skip-worktree bits. If you want to reduce your working tree to only deal with a subset of the files in the repository, we strongly encourage the use of git-sparse-checkout[1] in preference to the low-level update-index and read-tree primitives.

The primary purpose of the skip-worktree bit is to enable sparse checkouts, i.e. to have working directories with only a subset of paths present. When the skip-worktree bit is set, Git commands (such as switch, pull, merge) will avoid writing these files. However, these commands will sometimes write these files anyway in important cases such as conflicts during a merge or rebase. Git commands will also avoid treating the lack of such files as an intentional deletion; for example git add -u will not stage a deletion for these files and git commit -a will not make a commit deleting them either.

Although this bit looks similar to assume-unchanged bit, its goal is different. The assume-unchanged bit is for leaving the file in the working tree but having Git omit checking it for changes and presuming that the file has not been changed (though if it can determine without stat’ing the file that it has changed, it is free to record the changes). skip-worktree tells Git to ignore the absence of the file, avoid updating it when possible with commands that normally update much of the working directory (e.g. checkout, switch, pull, etc.), and not have its absence be recorded in commits. Note that in sparse checkouts (setup by git sparse-checkout or by configuring core.sparseCheckout to true), if a file is marked as skip-worktree in the index but is found in the working tree, Git will clear the skip-worktree bit for that file.

SPLIT INDEX

该模式专为拥有超大索引的仓库而设计,旨在减少重复写入这些索引所需的时间。

在这种模式下,索引被分割成两个文件:$GIT_DIR/index 和 $GIT_DIR/sharedindex.<SHA-1>。更改会累积到分割索引的 $GIT_DIR/index,而共享索引文件则包含所有索引条目并保持不变。

当拆分索引中的条目数达到 splitIndex.maxPercentChange 配置变量(参见 git-config[1])指定的水平时,拆分索引中的所有更改都会被推送回共享索引文件。

每次创建新的共享索引文件时,如果旧的共享索引文件的修改时间早于 splitIndex.sharedIndexExpire 配置变量(参见 git-config[1])的指定时间,则会被删除。

为避免删除仍在使用的共享索引文件,每次创建或读取基于共享索引文件的新拆分索引时,都会将其修改时间更新为当前时间。

UNTRACKED CACHE

该缓存的目的是加快涉及确定未跟踪文件(如 git status )的命令的执行速度。

该功能的工作原理是记录工作树目录的 mtime,然后省略读取目录和对 mtime 未发生变化的目录中文件的 stat 调用。要实现这一功能,如果目录中的文件被添加、修改或删除,底层操作系统和文件系统必须更改目录的 st_mtime 字段。

你可以使用`--test-untracked-cache` 选项来测试文件系统是否支持该功能。在旧版本的 Git 中,--untracked-cache 选项曾隐含地执行该测试,但现在已不再如此。

如果你想启用(或禁用)这项功能,使用 core.untrackedCache 配置变量(参见 git-config[1])比在每个版本库中使用 --untracked-cache 选项来 git update-index 要容易得多,尤其是如果你想在你使用的所有仓库中都这样做的话,因为你只需在 $HOME/.gitconfig 中将配置变量设置为 true (或 false )一次,它就会影响你接触的所有仓库。

当更改 core.untrackedCache 配置变量时,未跟踪缓存会在下一次命令读取索引时添加到索引中或从索引中移除;而当使用 --[no-|force-]untracked-cache 时,未跟踪缓存会立即添加到索引中或从索引中移除。

在 2.17 之前,untracked 缓存有一个 bug,即用指向另一个目录的符号链接替换一个目录会导致它错误地将 Git 追踪的文件显示为未追踪。参见 git.git 上的 "status: add a failing test showing a core.untrackedCache bug" 。解决这个问题的方法是(将来也可能适用于其他未被发现的 bug):

$ git -c core.untrackedCache=false status

当涉及到非跟踪缓存的内部结构时,这个 bug 也会影响到用文件替换目录的非符号链接情况,但还没有报告说这会导致错误的 "git status" 输出。

在某些情况下,由 2.17 之前版本的 Git 编写的现有索引会引用已不存在的目录,这可能会在 "git status" 上打印出许多 "could not open directory" (无法打开目录)的警告。这些警告是针对以前被默默丢弃的现有问题的新警告。

与上述错误一样,解决办法是一次性运行 core.untrackedCache=false 的 "git status" ,以清除剩余的坏数据。

文件系统监视器

该功能旨在加快工作目录较大的仓库的 Git 操作速度。

它能让 Git 与文件系统监视器(参见 git-fsmonitor--daemon[1]githooks[5] 中的 "fsmonitor-watchman" 部分)协同工作,监视器会告诉 Git 哪些文件被修改了。这样,Git 就不必通过 lstat() 来查找修改过的文件了。

与非跟踪缓存结合使用时,可以避免扫描整个工作目录寻找新文件的成本,从而进一步提高性能。

如果您想启用(或禁用)此功能,使用 core.fsmonitor 配置变量(参见 git-config[1])比在每个仓库中使用 -git update-index--fsmonitor 选项更方便,尤其是如果您想在您使用的所有仓库中启用(或禁用)此功能,因为您只需在 $HOME/.gitconfig 中设置一次配置变量,就能影响您接触的所有仓库。

更改 core.fsmonitor 配置变量后,文件系统监视器将在下一次命令读取索引时添加到索引或从索引中移除。当使用 --[no-]fsmonitor 时,文件系统监视器会立即添加到索引或从索引中移除。

配置

The command honors core.filemode configuration variable. If your repository is on a filesystem whose executable bits are unreliable, this should be set to false (see git-config[1]). This causes the command to ignore differences in file modes recorded in the index and the file mode on the filesystem if they differ only on executable bit. On such an unfortunate filesystem, you may need to use git update-index --chmod=.

与此类似,如果将 core.symlinks 配置变量设为 false(参见 git-config[1]),符号链接将作为普通文件签出,此命令不会将记录的文件模式从符号链接修改为普通文件。

The command looks at core.ignorestat configuration variable. See Using "assume unchanged" bit section above.

The command also looks at core.trustctime configuration variable. It can be useful when the inode change time is regularly modified by something outside Git (file system crawlers and backup systems use ctime for marking files processed) (see git-config[1]).

非跟踪缓存扩展可以通过 core.untrackedCache 配置变量启用(参见 git-config[1])。

注释

Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked. This does not work as expected, since Git may still check working tree files against the index when performing certain operations. In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.

For example, if the file you want to change is some sort of config file, the repository can include a sample config file that can then be copied into the ignored name and modified. The repository can even include a script to treat the sample file as a template, modifying and copying it automatically.

GIT

属于 git[1] 文档

scroll-to-top