【Git】从入门到精通(七)—— git status:查看仓库状态

前言

如果说 git commit 是Git的"快门",那 git status 就是Git的"仪表盘"。每次操作前后看一眼 git status,能让你清楚知道:现在工作区有什么改动?哪些已经暂存?哪些还没被Git跟踪?当前在哪个分支?

git status 是Git中使用频率最高的命令之一,几乎所有Git工作流都以它开始、以它结束。本篇将带你彻底读懂它的每一种输出。


一、git status 的作用

git status 用于查看工作区和暂存区的当前状态,主要告诉你:

  1. 当前在哪个分支
  2. 工作区有哪些文件被修改了(还未add)
  3. 暂存区有哪些文件(已经add,还未commit)
  4. 有哪些新文件还没被Git跟踪
  5. 有哪些文件被删除了
  6. 是否有合并冲突

它是你与Git"对话"的第一步------不知道当前状态,就无法决定下一步做什么。


二、基本用法和输出解读

2.1 无变更时的输出

复制代码
git status

输出:

复制代码
位于分支 main
无文件要提交,干净的工作区(clean working tree)

英文版:

复制代码
On branch main
nothing to commit, working tree clean

这说明:工作区和暂存区都没有任何变化,所有修改都已提交。

2.2 有未跟踪文件

新建了一个文件但还没 git add:

复制代码
echo "console.log('hello')" > new.js
git status

输出:

复制代码
位于分支 main
未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
        new.js

提示:您有未跟踪的文件,但尚未包含在提交中。
提示:将使用 'git add' 建立对此文件版本的跟踪。
提示:提交为空但是存在尚未跟踪的文件(使用 'git add' 建立跟踪)

解读:

  • 未跟踪的文件:Git知道这个文件存在,但还没纳入版本管理
  • 提示信息告诉你:用 git add 可以开始跟踪它

2.3 有已暂存文件

复制代码
git add new.js
git status

输出:

复制代码
位于分支 main
要提交的变更:
  (使用 "git restore --staged <文件>..." 以取消暂存)
        新文件:   new.js

解读:

  • 要提交的变更:这些文件已在暂存区,等待 git commit
  • 新文件: 表示这是新加入跟踪的文件
  • 提示告诉你:用 git restore --staged 可以把它从暂存区撤回

2.4 有已修改未暂存文件

修改一个已跟踪文件:

复制代码
echo "console.log('updated')" >> app.js
git status

输出:

复制代码
位于分支 main
修改尚未加入提交:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
        修改:    app.js

修改尚未加入提交:
        app.js

解读:

  • 修改尚未加入提交:文件被修改了,但还没 git add
  • 修改: 表示这是一个已跟踪文件被修改
  • 两个提示:git add 暂存它,或 git restore 丢弃修改

2.5 综合状态

最常见的情况------多种状态同时存在:

复制代码
git status

输出:

复制代码
位于分支 main
要提交的变更:
  (使用 "git restore --staged <文件>..." 以取消暂存)
        新文件:   config.js
        修改:    router.js

尚未暂存以备提交的变更:
  (使用 "git add <文件>..." 更新要提交的内容)
  (使用 "git restore <文件>..." 丢弃工作区的改动)
        修改:    app.js

未跟踪的文件:
  (使用 "git add <文件>..." 以包含要提交的内容)
        temp.js

这个输出清晰地分三栏:

区域 含义 文件
要提交的变更 已暂存,待commit config.js, router.js
尚未暂存 已修改,未add app.js
未跟踪的文件 新文件,Git不管理 temp.js

三、git status -s 简洁模式

-s 或 --short 选项输出极简格式,适合快速浏览:

复制代码
git status -s

输出:

复制代码
A  config.js
M  router.js
 M app.js
?? temp.js

3.1 输出格式解读

格式为 XY filename:

  • X:暂存区状态(第一列)
  • Y:工作区状态(第二列)
  • 两个状态之间可能有空格

3.2 状态标记含义表

标记 含义
未修改
M 修改(Modified)
A 新增(Added,已暂存)
D 删除(Deleted)
R 重命名(Renamed)
C 复制(Copied)
U 冲突(Unmerged,合并冲突)
?? 未跟踪(Untracked)
!! 被忽略(Ignored)

3.3 两列状态的含义

复制代码
M  file.js   # 暂存区有修改(已add),工作区无额外修改
 M file.js   # 工作区有修改(未add),暂存区无修改
MM file.js   # 暂存区有修改,且工作区又有新的修改
A  file.js   # 新增并已暂存
AM file.js   # 新增已暂存,且工作区又修改了
?? file.js   # 未跟踪

举例演示 MM 状态:

复制代码
echo "v1" > file.js
git add file.js        # 暂存区:v1
echo "v2" >> file.js   # 工作区:v1+v2
git status -s
# 输出:AM file.js(如果是新文件)

四、git status --long 详细模式(默认)

--long 是默认行为,就是上面看到的那种详细输出。显式使用:

复制代码
git status --long

通常不需要显式写,因为默认就是long。但如果你配置了 status.short 为true,可以用 --long 临时切换回详细模式。

复制代码
# 配置默认使用短格式
git config --global status.short true

# 临时用长格式
git status --long

五、git status -b 显示分支信息

-b 或 --branch 选项在输出顶部显示分支信息,常和 -s 组合使用:

复制代码
git status -sb

输出:

复制代码
## main...origin/main [领先 2]
A  config.js
 M app.js
?? temp.js

分支行解读:

  • ## main...origin/main:当前分支 main,跟踪远程 origin/main
  • [领先 2]:本地比远程多2个提交(ahead 2)
  • [落后 1]:本地比远程少1个提交(behind 1)
  • [领先 2, 落后 1]:既领先又落后,需要先pull再push

长格式中分支信息默认就显示:

复制代码
git status -b

输出:

复制代码
位于分支 main
您的分支领先 'origin/main' 共 2 个提交。
  (使用 "git push" 来发布您的本地提交)

要提交的变更:
        新文件:   config.js
...

六、git status --ignored 显示被忽略的文件

.gitignore 排除的文件默认不显示。用 --ignored 可以查看:

复制代码
# .gitignore 内容
# node_modules/
# *.log

git status --ignored

输出:

复制代码
位于分支 main
要提交的变更:
        新文件:   config.js

忽略的文件:
  (使用 "git add -f <文件>..." 以包含要提交的内容)
        .gitignore
        node_modules/
        error.log

配合 -s 简洁模式:

复制代码
git status -s --ignored

输出:

复制代码
A  config.js
!! node_modules/
!! error.log

!! 表示被忽略的文件。


七、git status --porcelain 机器可读格式

--porcelain 输出固定格式,适合脚本解析(不会随Git版本变化而改变):

复制代码
git status --porcelain

输出:

复制代码
A  config.js
 M app.js
?? temp.js

看起来和 -s 一样,但 --porcelain 保证格式稳定,而 -s 可能随版本更新变化。

7.1 porcelain v2

更详细的机器可读格式:

复制代码
git status --porcelain=v2

输出:

复制代码
# branch.head main
# branch.upstream origin/main
# branch.ab +2 0
1 A. N... 100644 100644 100644 a1b2c3d e5f6a7b config.js
1 .M N... 100644 100644 100644 b2c3d4e f6a7b8c app.js
? temp.js

每行含义:

  • # 开头:分支信息
  • 1 开头:已跟踪文件的状态
  • ? 开头:未跟踪文件
  • 2 开头:重命名/复制的文件
  • u 开头:冲突文件

7.2 在脚本中使用

复制代码
#!/bin/bash
# 检查是否有未提交的修改
if [ -n "$(git status --porcelain)" ]; then
  echo "有未提交的修改,请先提交"
  exit 1
fi
echo "工作区干净,可以继续"

八、各种场景下的 git status

8.1 新建文件后

复制代码
echo "content" > new.txt
git status

输出:

复制代码
位于分支 main
未跟踪的文件:
        new.txt

8.2 git add 后

复制代码
git add new.txt
git status

输出:

复制代码
位于分支 main
要提交的变更:
        新文件:   new.txt

8.3 git commit 后

复制代码
git commit -m "添加new.txt"
git status

输出:

复制代码
位于分支 main
无文件要提交,干净的工作区

8.4 修改已跟踪文件后

复制代码
echo "more" >> app.js
git status

输出:

复制代码
位于分支 main
修改尚未加入提交:
        修改:    app.js

8.5 删除文件后

方式一:直接用rm删除(工作区删除)

复制代码
rm old.js
git status

输出:

复制代码
位于分支 main
修改尚未加入提交:
        删除:    old.js

方式二:用git rm删除(同时从工作区和暂存区删除)

复制代码
git rm old.js
git status

输出:

复制代码
位于分支 main
要提交的变更:
        删除:    old.js

8.6 重命名文件后

复制代码
git mv old_name.js new_name.js
git status

输出:

复制代码
位于分支 main
要提交的变更:
        重命名:   old_name.js -> new_name.js

如果是普通 mv 而非 git mv:

复制代码
mv old_name.js new_name.js
git status

输出:

复制代码
位于分支 main
修改尚未加入提交:
        删除:    old_name.js

未跟踪的文件:
        new_name.js

Git会识别为"删除+新增",git add 后会自动识别为重命名:

复制代码
git add -A
git status

输出:

复制代码
位于分支 main
要提交的变更:
        重命名:   old_name.js -> new_name.js

8.7 合并冲突时

复制代码
git merge feature-branch
# 冲突!
git status

输出:

复制代码
位于分支 main
您有尚未合并的路径。
  (解决冲突并运行 "git commit")
  (使用 "git merge --abort" 终止合并)

要提交的变更:
        修改:    no-conflict.js

双方修改:
        修改:    conflict.js

解读:

  • 您有尚未合并的路径:正在合并中,有冲突
  • 双方修改:两边都改了同一个文件,需要手动解决
  • 解决后 git add conflict.js 再 git commit

冲突文件的状态标记详解:

复制代码
git status -s

输出:

复制代码
UU conflict.js      # 双方都修改了(Both Modified)
AA both-added.js    # 双方都新增了(Both Added)
DD both-deleted.js  # 双方都删除了(Both Deleted)
AU added-by-us.js   # 我们新增,对方修改
UA added-by-them.js # 对方新增,我们修改
DU deleted-by-us.js # 我们删除,对方修改
UD deleted-by-them.js # 对方删除,我们修改

8.8 rebase冲突时

复制代码
git rebase feature-branch
# 冲突!
git status

输出:

复制代码
交互式 rebase 正在进行中;至 8f3a2d1
(使用 "git rebase --continue" 继续变基)
(使用 "git rebase --skip" 跳过此补丁)
(使用 "git rebase --abort" 终止变基)

您有尚未合并的路径。
  (解决冲突并运行 "git rebase --continue")

双方修改:
        修改:    conflict.js

8.9 cherry-pick冲突时

复制代码
git cherry-pick 8f3a2d1
# 冲突!
git status

输出:

复制代码
位于分支 main
您目前正 cherry-pick 提交 8f3a2d1。
  (解决冲突并运行 "git cherry-pick --continue")
  (使用 "git cherry-pick --skip" 跳过此操作)
  (使用 "git cherry-pick --abort" 终止此操作)

双方修改:
        修改:    conflict.js

九、自定义 status 格式和颜色

9.1 自定义颜色

复制代码
# 开启颜色
git config --global color.status auto

# 自定义各种状态的颜色
git config --global color.status.added "green bold"
git config --global color.status.changed "yellow bold"
git config --global color.status.untracked "red bold"
git config --global color.status.header "blue"

9.2 自定义分支信息格式

复制代码
# 显示更多信息
git config --global status.branch true
git config --global status.displayCommentPrefix true

9.3 显示前置注释提示

默认的中文提示中那些括号里的帮助文字,可以关闭:

复制代码
git config --global status.displayCommentPrefix false

十、git status 的性能

在大型仓库中,git status 可能很慢,主要瓶颈在未跟踪文件的检测。

10.1 --untracked-files 选项

复制代码
# 默认:显示所有未跟踪文件(normal)
git status --untracked-files=normal

# 不显示未跟踪文件(最快)
git status --untracked-files=no
# 简写
git status -uno

# 显示未跟踪文件,包括被忽略目录里的(all)
git status --untracked-files=all
# 简写
git status -uall

normal 和 all 的区别:

  • normal:如果一个目录里全是未跟踪文件,只显示目录名
  • all:逐个显示每个文件

10.2 大仓库优化建议

  1. 善用 .gitignore :把 node_modules/、dist/ 等排除

  2. 用 -uno 快速检查:只看已跟踪文件的状态

  3. 配置默认行为:

    默认不显示未跟踪文件(加快速度)

    git config --global status.showUntrackedFiles no

  4. 使用Git的文件系统监控(Git 2.37+):

    git config --global core.fsmonitor true
    git config --global core.untrackedcache true

这能让Git缓存文件系统状态,大幅提升 git status 速度。


十一、常见问题 FAQ

Q1:git status 显示 "HEAD detached at ..."

说明当前处于"分离头指针"状态,通常发生在checkout到某个commit而非分支时:

复制代码
头指针分离于 8f3a2d1
无文件要提交,干净的工作区

此时提交不会属于任何分支。解决:

复制代码
git checkout main  # 回到分支
# 或创建新分支保存当前状态
git checkout -b new-branch

Q2:git status 显示中文文件名是乱码

复制代码
git config --global core.quotepath false

默认Git会把非ASCII字符转义显示,这个配置关闭转义。

Q3:git status 很慢怎么办?

参考第十节优化建议,主要:

  • 完善 .gitignore
  • 使用 core.fsmonitor
  • 临时用 git status -uno

Q4:如何只看是否有变化(不看具体内容)?

复制代码
# 用porcelain格式判断
if [ -z "$(git status --porcelain)" ]; then
  echo "无变化"
fi

Q5:git status 显示 "您的分支落后于..."

复制代码
位于分支 main
您的分支落后 'origin/main' 共 3 个提交,并且可以快进。
  (使用 "git pull" 来更新您的本地分支)

说明远程有新提交,本地需要 git pull。

Q6:ahead 和 behind 同时存在?

复制代码
您的分支和 'origin/main' 产生了分叉,
并且分别有 2 和 1 处不同的提交。

说明本地和远程都各自有提交,需要先 git pull 合并再 git push。

Q7:git status 显示 "interactive rebase in progress"

说明你正在执行 git rebase -i 交互式变基,处于暂停状态。可以:

复制代码
git rebase --continue  # 解决冲突后继续
git rebase --skip      # 跳过当前提交
git rebase --abort     # 放弃rebase回到之前

Q8:如何让git status不显示某些文件?

把这些文件加入 .gitignore:

复制代码
echo "*.log" >> .gitignore
echo "node_modules/" >> .gitignore

如果文件已经被跟踪,需要先取消跟踪:

复制代码
git rm --cached debug.log
echo "debug.log" >> .gitignore

Q9:git status -s 中第一列和第二列的区别?

复制代码
XY filename
  • X(第一列):暂存区相对HEAD的状态(已add的改动)
  • Y(第二列):工作区相对暂存区的状态(未add的改动)

例如 MM file.js:

  • 第一个M:暂存区有修改(已add)
  • 第二个M:工作区又有新修改(未add)

Q10:如何查看暂存区里有什么?

复制代码
# 查看暂存区文件列表
git ls-files --stage

# 查看暂存区状态
git diff --staged --stat

十二、小结

本篇详细讲解了 git status 命令:

知识点 要点
作用 查看工作区和暂存区状态
基本输出 分三栏:要提交、未暂存、未跟踪
-s 简洁模式 XY filename 格式,X暂存区Y工作区
-b 分支信息 显示ahead/behind情况
--ignored 显示被.gitignore排除的文件
--porcelain 机器可读格式,用于脚本
常见场景 新建/修改/删除/重命名/合并冲突
性能优化 .gitignore、fsmonitor、-uno

12.1 git status 输出的三个区域

再次强调,git status 的输出分为三个区域,理解这三个区域是掌握Git的关键:

区域一:要提交的变更(Changes to be committed)

这些文件已经在暂存区,执行 git commit 就会进入版本库。对应 git add 过的文件。

复制代码
要提交的变更:
        新文件:   new.js        # 新增并暂存
        修改:    app.js        # 修改并暂存
        删除:    old.js        # 删除并暂存

区域二:尚未暂存以备提交的变更(Changes not staged for commit)

这些文件已被Git跟踪,且工作区有修改,但还没 git add。执行 git commit 不会包含它们。

复制代码
尚未暂存以备提交的变更:
        修改:    router.js     # 修改了但没add

区域三:未跟踪的文件(Untracked files)

这些文件在工作区存在,但Git还没纳入管理。需要 git add 才能开始跟踪。

复制代码
未跟踪的文件:
        temp.js                # 新文件,还没被Git管理

12.2 状态转换图

文件在这三个区域之间的转换:

复制代码
未跟踪 ──git add──▶ 已暂存 ──git commit──▶ 已提交
  ▲                  │                      │
  │                  │git restore --staged  │
  │                  ▼                      │
  └─────────  已修改未暂存 ◀────────────────┘
                   │
                   │git restore
                   ▼
                已恢复原样

核心记忆:

复制代码
git status              # 查看详细状态
git status -s           # 简洁模式
git status -sb          # 简洁+分支信息(最常用)
git status --ignored    # 显示被忽略文件
git status --porcelain  # 脚本用格式

养成习惯 :每次 git add 前看一眼 git status,每次 git commit 前看一眼,每次 git pull/push 前看一眼。这是避免Git操作失误的最简单方法。

下一篇我们将学习 git log------如何查看提交历史,追溯每一次修改的来龙去脉。


作者:全栈陈序员 出处:CSDN 声明:本文为原创文章,转载请注明出处

相关推荐
fengye2071612 小时前
第三章 编译cpython
大数据·elasticsearch·搜索引擎
大大大大晴天2 小时前
每天认识一个组件:Apache Flink
大数据
涛思数据(TDengine)2 小时前
从工业本体到 AI 原生:TDengine 出席 2026 QCon 分享工业数据基础设施路径
大数据·数据库·人工智能·tdengine·工业
Gu_WenYun3 小时前
从主题定价到订单定价:机器人基金的产业链观察
大数据·人工智能·金融
其实防守也摸鱼3 小时前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php
刀笔财经3 小时前
新时达的选择:先造血,再谈利润
大数据
Bode_20024 小时前
精益制造推行成熟度与核心量化评估体系
大数据·人工智能
莫晓燚5 小时前
Ansible 13 个常用模块---企业实战
git·github
超级新零售6 小时前
AI 零售软件是什么?从库存提醒到智能调货的系统分工
大数据·人工智能·零售