简体中文 ▾ 主题 ▾ 最新版本 ▾ git-status 最后更新于 2.45.0

名称

git-status - 显示工作区状态

概要

git status [<options>] [--] [<pathspec>…​]

描述

显示索引文件与当前 HEAD 提交之间有差异的路径,工作区与索引文件之间有差异的路径,以及工作区中未被 Git 跟踪(且未被 gitignore[5] 忽略)的路径。第一种是运行 git commit 将要提交的内容;第二种和第三种是运行 git commit 之前通过运行 git add 可以提交的内容。

选项

-s
--short

以短格式输出。

-b
--branch

即使是短格式,也显示分支和跟踪信息。

--show-stash

显示当前暂存条目的数量。

--porcelain[=<version>]

以易于脚本解析的格式输出。这类似于短格式输出,但在 Git 版本之间和用户配置下保持稳定。详情见下文。

版本参数用于指定格式版本。这是可选的,默认为原始版本 v1 格式。

--long

以长格式输出。这是默认设置。

-v
--verbose

除了显示已更改文件的名称外,还显示已暂存待提交的文本更改(即,类似于 git diff --cached 的输出)。如果指定两次 -v,则还显示工作区中尚未暂存的更改(即,类似于 git diff 的输出)。

-u[<mode>]
--untracked-files[=<mode>]

显示未跟踪的文件。

模式参数用于指定未跟踪文件的处理方式。它是可选的:默认为 all,如果指定,则必须与选项紧密相连(例如 -uno,而不是 -u no)。

可能的选项是

  • no - 不显示任何未跟踪的文件。

  • normal - 显示未跟踪的文件和目录。

  • all - 还显示未跟踪目录中的单个文件。

当不使用 -u 选项时,会显示未跟踪的文件和目录(即与指定 normal 相同),以帮助您避免忘记添加新创建的文件。由于在文件系统中查找未跟踪文件需要额外的工作,在大型工作区中此模式可能需要一些时间。如果支持,请考虑启用未跟踪缓存和分段索引(参见 git update-index --untracked-cachegit update-index --split-index),否则您可以使用 no 来让 git status 更快地返回而不显示未跟踪文件。布尔值 true 的所有常用拼写都被视为 normalfalse 被视为 no

默认值可以通过 git-config[1] 中所述的 status.showUntrackedFiles 配置变量进行更改。

--ignore-submodules[=<when>]

查找更改时忽略子模块的更改。<when> 可以是 "none"、"untracked"、"dirty" 或 "all"(默认值)。使用 "none" 将在子模块包含未跟踪文件或修改文件,或者其 HEAD 与超级项目中记录的提交不同时,将其视为已修改,并可用于覆盖 git-config[1]gitmodules[5]ignore 选项的任何设置。当使用 "untracked" 时,如果子模块只包含未跟踪内容,则不将其视为脏(但仍会扫描其修改内容)。使用 "dirty" 忽略子模块工作区的所有更改,只显示超级项目中存储的提交的更改(这是 1.7.0 之前的行为)。使用 "all" 隐藏所有子模块的更改(并在设置了配置选项 status.submoduleSummary 时抑制子模块摘要的输出)。

--ignored[=<mode>]

也显示被忽略的文件。

模式参数用于指定被忽略文件的处理方式。它是可选的:默认为 traditional

可能的选项是

  • traditional - 显示被忽略的文件和目录,除非指定了 --untracked-files=all,在这种情况下,将显示被忽略目录中的单个文件。

  • no - 不显示被忽略的文件。

  • matching - 显示与忽略模式匹配的被忽略文件和目录。

当指定 matching 模式时,将显示明确匹配忽略模式的路径。如果一个目录匹配忽略模式,则显示该目录,但不显示该忽略目录中包含的路径。如果一个目录不匹配忽略模式,但所有内容都被忽略,则不显示该目录,但显示所有内容。

-z

用 NUL 终止条目,而不是 LF。如果没有给出其他格式,这意味着 --porcelain=v1 输出格式。

--column[=<options>]
--no-column

以列显示未跟踪文件。有关选项语法,请参见配置变量 column.status--column 和不带选项的 --no-column 分别等同于 alwaysnever

--ahead-behind
--no-ahead-behind

显示或不显示分支相对于其上游分支的详细领先/落后计数。默认为 true。

--renames
--no-renames

无论用户配置如何,开启/关闭重命名检测。另请参见 git-diff[1] --no-renames

--find-renames[=<n>]

开启重命名检测,可选地设置相似度阈值。另请参见 git-diff[1] --find-renames

<pathspec>…​

请参阅 gitglossary[7] 中的 pathspec 条目。

输出

此命令的输出旨在用作提交模板注释。默认的长格式旨在人类可读、详细和描述性强。其内容和格式可能随时更改。

输出中提到的路径,与许多其他 Git 命令不同,如果您在子目录中工作,则它们是相对于当前目录的(这是故意的,有助于剪切和粘贴)。请参阅下面的 status.relativePaths 配置选项。

短格式

在短格式中,每个路径的状态以以下形式之一显示

XY PATH
XY ORIG_PATH -> PATH

其中 ORIG_PATH 是重命名/复制内容来自的原始路径。ORIG_PATH 仅在条目被重命名或复制时显示。XY 是两位状态码。

字段(包括 ->)之间用一个空格分隔。如果文件名包含空白或其他不可打印字符,则该字段将以 C 字符串文字的方式引用:由 ASCII 双引号(34)字符包围,内部特殊字符用反斜杠转义。

使用此格式显示三种不同类型的状态,每种都以不同的方式使用 XY 语法

  • 当合并正在发生且合并成功时,或在合并情况之外,X 显示索引的状态,Y 显示工作区的状态。

  • 当发生合并冲突且尚未解决时,XY 显示每个合并头相对于共同祖先引入的状态。这些路径被称为 未合并

  • 当路径未被跟踪时,XY 总是相同的,因为它们对索引是未知的。?? 用于未跟踪的路径。除非使用 --ignored,否则不会列出被忽略的文件;如果使用,被忽略的文件用 !! 表示。

请注意,此处的 合并 术语还包括使用默认 --merge 策略进行的变基、cherry-pick 以及任何其他使用合并机制的操作。

在下表中,这三类在单独的部分中显示,这些字符用于显示跟踪路径的前两个部分的 XY 字段

  • ' ' = 未修改

  • M = 已修改

  • T = 文件类型已更改(普通文件、符号链接或子模块)

  • A = 已添加

  • D = 已删除

  • R = 已重命名

  • C = 已复制(如果配置选项 status.renames 设置为 "copies")

  • U = 已更新但未合并

X          Y     Meaning
-------------------------------------------------
	 [AMD]   not updated
M        [ MTD]  updated in index
T        [ MTD]  type changed in index
A        [ MTD]  added to index
D                deleted from index
R        [ MTD]  renamed in index
C        [ MTD]  copied in index
[MTARC]          index and work tree matches
[ MTARC]    M    work tree changed since index
[ MTARC]    T    type changed in work tree since index
[ MTARC]    D    deleted in work tree
	    R    renamed in work tree
	    C    copied in work tree
-------------------------------------------------
D           D    unmerged, both deleted
A           U    unmerged, added by us
U           D    unmerged, deleted by them
U           A    unmerged, added by them
D           U    unmerged, deleted by us
A           A    unmerged, both added
U           U    unmerged, both modified
-------------------------------------------------
?           ?    untracked
!           !    ignored
-------------------------------------------------

子模块有更多状态并报告

  • M = 子模块的 HEAD 与索引中记录的不同

  • m = 子模块有修改的内容

  • ? = 子模块有未跟踪的文件

这是因为子模块中修改的内容或未跟踪的文件无法通过超级项目中的 git add 添加以准备提交。

m? 递归应用。例如,如果子模块中的嵌套子模块包含未跟踪文件,这也报告为 ?

如果使用 -b,则短格式状态前面会有一行

## branchname tracking info

Porcelain 格式版本 1

版本 1 porcelain 格式类似于短格式,但保证在 Git 版本之间或基于用户配置不会发生向后不兼容的更改。这使其非常适合脚本解析。上述短格式的描述也适用于 porcelain 格式,但有以下几个例外

  1. 不遵守用户的 color.status 配置;颜色将始终关闭。

  2. 不遵守用户的 status.relativePaths 配置;显示的路径将始终相对于仓库根目录。

还有一个建议用于机器解析的替代 -z 格式。在该格式中,状态字段相同,但其他一些内容发生了变化。首先,重命名条目中的 -> 被省略,并且字段顺序颠倒(例如 from -> to 变为 to from)。其次,每个文件名后跟一个 NUL(ASCII 0),取代空格作为字段分隔符和终止换行符(但空格仍然分隔状态字段和第一个文件名)。第三,包含特殊字符的文件名没有特殊格式;不执行引号或反斜杠转义。

任何子模块更改都报告为已修改 M,而不是 m 或单个 ?

Porcelain 格式版本 2

版本 2 格式增加了关于工作区状态和已更改项目的更详细信息。版本 2 还定义了一组可扩展的、易于解析的可选标头。

标头行以 "#" 开头,并根据特定的命令行参数添加。解析器应忽略它们无法识别的标头。

分支标头

如果给定 --branch,则打印一系列标头行,其中包含有关当前分支的信息。

Line                                     Notes
------------------------------------------------------------
# branch.oid <commit> | (initial)        Current commit.
# branch.head <branch> | (detached)      Current branch.
# branch.upstream <upstream-branch>      If upstream is set.
# branch.ab +<ahead> -<behind>           If upstream is set and
					 the commit is present.
------------------------------------------------------------

暂存信息

如果给定 --show-stash,则如果暂存条目数量不为零,则打印一行显示暂存条目的数量

# stash <N>

已更改的跟踪条目

在标头之后,为跟踪条目打印一系列行。根据更改的类型,可以使用三种不同的行格式之一来描述条目。跟踪条目以未定义的顺序打印;解析器应允许三种行类型以任何顺序混合。

普通更改的条目具有以下格式

1 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <path>

重命名或复制的条目具有以下格式

2 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <X><score> <path><sep><origPath>
Field       Meaning
--------------------------------------------------------
<XY>        A 2 character field containing the staged and
	    unstaged XY values described in the short format,
	    with unchanged indicated by a "." rather than
	    a space.
<sub>       A 4 character field describing the submodule state.
	    "N..." when the entry is not a submodule.
	    "S<c><m><u>" when the entry is a submodule.
	    <c> is "C" if the commit changed; otherwise ".".
	    <m> is "M" if it has tracked changes; otherwise ".".
	    <u> is "U" if there are untracked changes; otherwise ".".
<mH>        The octal file mode in HEAD.
<mI>        The octal file mode in the index.
<mW>        The octal file mode in the worktree.
<hH>        The object name in HEAD.
<hI>        The object name in the index.
<X><score>  The rename or copy score (denoting the percentage
	    of similarity between the source and target of the
	    move or copy). For example "R100" or "C75".
<path>      The pathname.  In a renamed/copied entry, this
	    is the target path.
<sep>       When the `-z` option is used, the 2 pathnames are separated
	    with a NUL (ASCII 0x00) byte; otherwise, a tab (ASCII 0x09)
	    byte separates them.
<origPath>  The pathname in the commit at HEAD or in the index.
	    This is only present in a renamed/copied entry, and
	    tells where the renamed/copied contents came from.
--------------------------------------------------------

未合并的条目具有以下格式;第一个字符是 "u",以区别于普通更改的条目。

u <XY> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>
Field       Meaning
--------------------------------------------------------
<XY>        A 2 character field describing the conflict type
	    as described in the short format.
<sub>       A 4 character field describing the submodule state
	    as described above.
<m1>        The octal file mode in stage 1.
<m2>        The octal file mode in stage 2.
<m3>        The octal file mode in stage 3.
<mW>        The octal file mode in the worktree.
<h1>        The object name in stage 1.
<h2>        The object name in stage 2.
<h3>        The object name in stage 3.
<path>      The pathname.
--------------------------------------------------------

其他项目

在跟踪条目之后(如果请求),将打印一系列行,用于工作区中找到的未跟踪项目,然后是被忽略的项目。

未跟踪项目具有以下格式

? <path>

被忽略项目具有以下格式

! <path>

路径名格式注意事项和 -z

当给出 -z 选项时,路径名按原样打印,不带任何引用,并且行以 NUL (ASCII 0x00) 字节终止。

如果没有 -z 选项,则包含“不寻常”字符的路径名将按照配置变量 core.quotePath 的解释进行引用(参见 git-config[1])。

配置

该命令遵循 color.status(或 status.color — 它们含义相同,后者是为了向后兼容而保留)和 color.status.<slot> 配置变量来对输出着色。

如果配置变量 status.relativePaths 设置为 false,则显示的所有路径都是相对于仓库根目录的,而不是相对于当前目录的。

如果 status.submoduleSummary 设置为非零数字或 true(等同于 -1 或无限数字),则长格式的子模块摘要将被启用,并显示修改过的子模块的提交摘要(参见 git-submodule[1] 的 --summary-limit 选项)。请注意,当 diff.ignoreSubmodules 设置为 all 或仅当 submodule.<name>.ignore=all 时,状态命令的摘要输出将对所有子模块被抑制。要查看被忽略子模块的摘要,您可以使用 --ignore-submodules=dirty 命令行选项或 git submodule summary 命令,该命令显示类似的输出但不遵循这些设置。

后台刷新

默认情况下,git status 会自动刷新索引,从工作区更新缓存的统计信息并写入结果。写入更新后的索引是一种优化,并非严格必要(status 本身会计算这些值,但写入它们只是为了避免后续程序重复我们的计算)。当 status 在后台运行时,写入期间持有的锁可能会与其他同时进行的进程冲突,导致它们失败。在后台运行 status 的脚本应考虑使用 git --no-optional-locks status(详情参见 git[1])。

未跟踪文件和性能

git status 在大型工作区中搜索未跟踪文件和目录时可能会非常慢。有许多配置选项可以加快此速度,通过避免工作或利用先前 Git 命令的缓存结果。没有一个单一的最优设置适合所有人。我们将列出相关选项的摘要以帮助您,但在进入列表之前,您可能想再次运行 git status,因为您的配置可能已经缓存了 git status 结果,因此在后续运行中可能会更快。

  • --untracked-files=no 标志或 status.showUntrackedFiles=no 配置(两者均见上文):指示 git status 不应报告未跟踪文件。这是最快的选项。git status 不会列出未跟踪文件,因此您需要小心记住是否创建了任何新文件并手动 git add 它们。

  • advice.statusUoption=false(参见 git-config[1]):将此变量设置为 false 可禁用在枚举未跟踪文件超过 2 秒时发出的警告消息。在大型项目中,这可能需要更长时间,并且用户可能已经接受了权衡(例如,使用 “-uno” 可能不是用户可以接受的选项),在这种情况下,发出警告消息没有意义,禁用警告可能是最好的选择。

  • core.untrackedCache=true(参见 git-update-index[1]):启用未跟踪缓存功能,并且只搜索自上次 git status 命令以来已修改的目录。Git 会记住每个目录中未跟踪文件的集合,并假定如果目录未被修改,则其中未跟踪文件的集合也未更改。这比枚举每个目录的内容快得多,但仍有成本,因为 Git 仍然需要搜索已修改目录的集合。未跟踪缓存存储在 .git/index 文件中。搜索未跟踪文件的成本降低被索引文件大小的增加以及保持其最新状态的成本稍微抵消。通常,减少的搜索时间值得额外的文件大小。

  • core.untrackedCache=truecore.fsmonitor=truecore.fsmonitor=<hook-command-pathname>(参见 git-update-index[1]):同时启用未跟踪缓存和 FSMonitor 功能,并且只搜索自上次 git status 命令以来已修改的目录。这比单独使用未跟踪缓存更快,因为 Git 还可以避免搜索已修改的目录。Git 只需枚举最近已更改的精确目录集。虽然可以在不启用未跟踪缓存的情况下启用 FSMonitor 功能,但在这种情况下,收益会大大降低。

请注意,启用未跟踪缓存和/或 FSMonitor 功能后,可能需要运行几次 git status 命令才能使各种缓存预热,然后才能看到命令时间的改善。这是正常的。

另请参阅

GIT

Git[1] 套件的一部分

scroll-to-top