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

名称

git-status - 显示工作区状态

概要

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

描述

显示暂存区(index)文件与当前 HEAD 提交之间有差异的路径、工作区与暂存区文件之间有差异的路径,以及工作区中未被 Git 跟踪(且未被 gitignore[5] 忽略)的路径。第一类路径是运行 git commit将会提交的内容;第二和第三类路径是你在运行 git commit 之前,可以通过运行 git add 来准备提交的内容。

选项

-s
--short

以短格式给出输出。

-b
--branch

即使在短格式下也显示分支和追踪信息。

--show-stash

显示当前贮藏(stash)条目的数量。

--porcelain[=<版本>]

为脚本提供一种易于解析的输出格式。这类似于短格式输出,但无论 Git 版本如何或用户配置如何,格式都将保持稳定。详见下文。

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

--long

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

-v
--verbose

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

-u[<模式>]
--untracked-files[=<模式>]

显示未跟踪的文件。

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

可选的选项包括:

no

不显示未跟踪的文件。

normal

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

all

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

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

默认值可以使用 git-config[1] 中记载的 status.showUntrackedFiles 配置变量进行更改。

--ignore-submodules[=<何时>]

在寻找更改时忽略子模块的更改。<何时> 可以是 noneuntrackeddirtyall(默认值)。

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

显示匹配忽略模式的忽略文件和目录。

显示显式匹配忽略模式的路径。如果一个目录匹配忽略模式,则显示该目录,但不显示该目录中包含的路径。如果一个目录不匹配忽略模式,但其所有内容都被忽略,则不显示该目录,但显示其所有内容。

-z

NUL 而不是 LF(换行符)结束条目。如果没有给出其他格式,则意味着使用 --porcelain=v1 输出格式。

--column[=<选项>]
--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

<路径规范>...

参见 gitglossary[7] 中的 pathspec 条目。

输出

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

与其他许多 Git 命令不同,如果你在子目录中工作,输出中提到的路径是相对于当前目录的(这是特意设计的,以便于剪切和粘贴)。请参阅下文的 status.relativePaths 配置选项。

短格式

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

<xy> <path>
<xy> <orig-path> -> <path>

其中 <orig-path> 是重命名/复制内容的来源。只有当条目被重命名或复制时,才会显示 <orig-path><xy> 是一个双字母状态代码 XY

各字段(包括 ->)彼此之间由单个空格分隔。如果文件名包含空格或其他不可打印字符,则该字段将按照 C 字符串字面量的方式引用:用 ASCII 双引号 (34) 括起来,并对内部特殊字符进行反斜杠转义。

使用此格式显示的状态有三种不同类型,每种类型使用 <xy> 语法的方式不同:

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

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

  • 当路径未跟踪时,XY 总是相同的,因为它们对暂存区来说是未知的。?? 用于未跟踪路径。除非使用了 --ignored,否则不列出被忽略的文件;如果使用了该选项,被忽略的文件由 !! 表示。

注意,这里的合并(merge)一词也包括使用默认 --merge 策略的变基(rebase)、拣选(cherry-pick)以及任何其他使用合并机制的操作。

下表中,这三类情况显示在不同的部分,并且对于显示已跟踪路径的前两个部分,XY 字段使用这些字符:

' '

未修改

M

已修改

T

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

A

已添加

D

已删除

R

已重命名

C

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

U

已更新但未合并

X Y 含义

[AMD]

未更新

M

[ MTD]

在暂存区中已更新

T

[ MTD]

在暂存区中类型已更改

A

[ MTD]

已添加到暂存区

D

从暂存区中删除

R

[ MTD]

在暂存区中已重命名

C

[ MTD]

在暂存区中已复制

[MTARC]

暂存区和工作区匹配

[ MTARC]

M

工作区自暂存后已更改

[ MTARC]

T

工作区自暂存后类型已更改

[ MTARC]

D

在工作区中已删除

R

在工作区中已重命名

C

在工作区中已复制

D

D

未合并,双方均删除

A

U

未合并,由我们添加

U

D

未合并,由对方删除

U

A

未合并,由对方添加

D

U

未合并,由我们删除

A

A

未合并,双方均添加

U

U

未合并,双方均修改

?

?

未跟踪

!

!

已忽略

子模块有更多状态,会报告:

M

子模块的 HEAD 与暂存区中记录的不同

m

子模块有已修改的内容

?

子模块有未跟踪的文件

这是因为子模块中已修改的内容或未跟踪的文件不能在父项目通过 git add 添加来准备提交。

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

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

{empty}## <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,则会打印一系列带有当前分支信息的标头行。

备注

# branch.oid <提交> | (initial)

当前提交。

# branch.head <分支> | (detached)

当前分支。

# branch.upstream <上游分支>

如果设置了上游。

# branch.ab +<领先> -<落后>

如果设置了上游且提交存在。

贮藏信息

如果给出了 --show-stash,且贮藏条目数不为零,则打印一行显示该数量

# stash <N>

已更改的已跟踪条目

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

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

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

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

2 <XY> <sub> <mH> <mI> <mW> <hH> <hI> <X><score> <path><sep><origPath>
字段 含义

<XY>

一个 2 字符字段,包含短格式中描述的已暂存和未暂存 XY 值,未更改的部分用 "." 而不是空格表示。

<sub>

描述子模块状态的 4 字符字段。当条目不是子模块时为 "N..."。当条目是子模块时为 S<c><m><u>

  • 如果提交已更改,<c> 为 "C";否则为 "."。

  • 如果有已跟踪的更改,<m> 为 "M";否则为 "."。

  • 如果有未跟踪的更改,<u> 为 "U";否则为 "."。

<mH>

HEAD 中的八进制文件模式。

<mI>

暂存区中的八进制文件模式。

<mW>

工作树中的八进制文件模式。

<hH>

HEAD 中的对象名称。

<hI>

暂存区中的对象名称。

<X><score>

重命名或复制评分(表示移动或复制的源和目标之间的相似性百分比)。例如 "R100" 或 "C75"。

<path>

路径名。在重命名/复制条目中,这是目标路径。

<sep>

使用 -z 选项时,两个路径名用 NUL (ASCII 0x00) 字节分隔;否则,用 TAB (ASCII 0x09) 字节分隔。

<origPath>

HEAD 提交中或暂存区中的路径名。这仅存在于重命名/复制条目中,说明重命名/复制内容的来源。

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

u <XY> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>
字段 含义

<XY>

一个 2 字符字段,如短格式中所述描述冲突类型。

<sub>

描述子模块状态的 4 字符字段,如上所述。

<m1>

第 1 阶段(stage 1)中的八进制文件模式。

<m2>

第 2 阶段中的八进制文件模式。

<m3>

第 3 阶段中的八进制文件模式。

<mW>

工作树中的八进制文件模式。

<h1>

第 1 阶段中的对象名称。

<h2>

第 2 阶段中的对象名称。

<h3>

第 3 阶段中的对象名称。

<path>

路径名。

其他项目

在已跟踪条目之后(如果请求),将为工作树中发现的未跟踪项目和被忽略项目打印一系列行。

未跟踪项目具有以下格式:

? <path>

被忽略项目具有以下格式:

! <path>

路径名格式说明与 -z

给定 -z 选项时,路径名按原样打印,不带任何引号,且行以 NUL (ASCII 0x00) 字节结束。

不带 -z 选项时,带有“特殊”字符的路径名将按照配置变量 core.quotePath 的说明进行引用(参见 git-config[1])。

配置

该命令遵循 color.status(或 status.color —— 它们含义相同,后者保留用于向后兼容)和 color.status.<位置> 配置变量来对其输出进行着色。

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

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

后台刷新

默认情况下,git status 会自动刷新暂存区,从工作树更新缓存的 stat 信息并写出结果。写出更新后的暂存区是一种优化,并非严格必要(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=<钩子命令路径名>(见 git-update-index[1]):同时启用未跟踪缓存和 FSMonitor 功能,仅搜索自上次 git status 命令以来已被修改的目录。这比单独使用未跟踪缓存更快,因为 Git 还可以避免搜索已修改的目录。Git 只需要列举最近发生变化的准确目录集。虽然可以在不使用未跟踪缓存的情况下启用 FSMonitor 功能,但这种情况下收益会大打折扣。

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

另请参阅

GIT

Git[1] 套件的一部分