前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Git 工作区 暂存区 仓库 三棵树
GiGit版本控制

Git 的工作区、暂存区和仓库三个状态分别存放什么,文件如何在三者之间流转

Git 的三个区域分别存放工作目录中的实际文件、下一次提交的候选快照、以及已提交的历史快照;文件通过 add、commit 等命令在它们之间流转。

前端进阶之旅 · 一题精讲更新于 2026.09.05
Git#版本控制
先看核心答案
理解线索

三棵树模型

  1. 工作区实际文件,可自由修改
  2. 暂存区index,保存下次提交内容
  3. 仓库提交对象与元数据,不可变

git status 对比的是工作区与暂存区、暂存区与仓库之间的差异。

核心回答

先记住这个答案

工作区是你直接编辑的文件目录,存放未跟踪或已修改但未暂存的实际内容;暂存区(index)记录下一次提交将纳入的文件快照,相当于候选提交清单;仓库(.git)保存所有已提交的不可变快照及元数据。文件流转路径是:工作区修改后,用 git add 把当前文件内容写入暂存区;用 git commit 将暂存区内容固化成一个新的提交存入仓库;git checkout 或 git restore 可从仓库或暂存区把内容写回工作区。

  • 工作区是实际文件目录,暂存区是下次提交的快照
  • git add 写入暂存区,git commit 固化到仓库
  • 未跟踪文件在 add 前不被 Git 记录

三棵树的存储机制与流转命令

工作区是磁盘上的文件树,直接对应你编辑的文件。Git 并不主动监控它,只有执行 git status 或 git diff 时才会扫描文件变化,将文件内容与暂存区中的记录比对。新文件未被跟踪,修改过的文件在暂存区没有对应新版本,会显示为 ‘Changes not staged’;这些内容依然保留在工作区中,但未被 Git 纳入版本管理。

暂存区(index)是一个二进制文件,保存了每个路径对应的 blob 对象哈希和文件模式。git add 会把当前工作区文件压缩成 blob 对象写入对象库,并把路径与哈希记录到 index 中。git commit 则读取 index 生成 tree 对象,再创建 commit 对象指向该 tree,并更新当前分支指针。仓库中存放的是已提交的全部快照,每次提交都是一个不可变对象。

git checkout 从仓库取出提交,将文件写入工作区并重设 index;git reset 的 --mixed 模式默认把仓库某提交的内容同步到 index,但不动工作区;git restore 可分别指定 --staged 或 --worktree 来精准回退。理解 index 是暂存区的实现,才能解释为什么 git add 后还需 git commit。

修改后只部分暂存再提交

假设你编辑了 docs/readme.md,既修复了错别字又添加了新章节。你希望两次提交分开,以便历史清晰。此时工作区文件是合并后的状态,但暂存区仍是旧版本。执行 git add docs/readme.md 会把当前完整文件都暂存,这不行;正确做法是用 git add -p 进入交互模式,按 hunk 选择性地暂存。选择某个 hunk 后,该部分的新内容进入暂存区,未选择的修改仍留在工作区。

提交后,暂存区与仓库一致,但工作区仍有残留修改未暂存。git status 会显示 ‘Changes not staged’。继续 git add 剩余部分再 commit,两个提交分别包含你的错别字修复和新章节。如果误提交了全部,可用 git reset --soft HEAD~1 撤销提交并保留暂存区内容,但若已推送则需谨慎改写历史。

文件类型的边界与未跟踪文件处理

工作区中未被跟踪的文件(新文件)在没有 git add 前,仓库和暂存区都没有它们的记录。git commit 不会包含它们,因为提交只基于 index 内容。要强行包含,必须显式 add。同理,.gitignore 只影响未跟踪文件的扫描,对已跟踪文件无效。这是初学者常混淆的边界:修改已跟踪文件,仓库旧版本还在;工作区新版本只是差异。

若丢弃未暂存修改,git restore <file> 会用 index 内容覆盖工作区;若丢弃已暂存修改,需要 git restore --staged 后再 checkout。但如果修改已被提交并推送到远程,就不能依赖本地覆盖,因为其他协作者可能已基于该提交工作。此时应使用 git revert 生成反向提交。记住:仓库对象是不可变的,reset 只是移动指针,真正丢失提交前可用 reflog 找回。

回答前,多想一步

容易答错的地方

认为 git commit 保存工作区所有修改
commit 只保存暂存区的快照。你修改文件但不 add,commit 不会包含这些修改。必须先 add 或使用 git commit -a(仅限已跟踪文件)才会暂存并提交。
以为暂存区存放文件副本
暂存区存放的是每个文件的 blob 对象哈希,而非完整文件副本。文件内容以压缩对象形式存于对象库,index 只是引用。因此 add 一个巨大文件实际上先创建对象,这可能是 git add 慢的原因。
试着用自己的话回答

面试官还会怎么问?

git diff 与 git diff --staged 有何区别?

git diff 比较工作区与暂存区的差异,git diff --staged(或 --cached)比较暂存区与仓库 HEAD 的差异。没有参数时默认只看工作区中未暂存的修改。

git status 中 'Changes to be committed' 意味着什么?

它表示暂存区与当前 HEAD 提交有差异,这些差异将在下一次提交中生效。但工作区可能还有未暂存修改,git status 会分组显示。

一次 commit 后暂存区为何不再显示变化?

因为 commit 会用 index 创建新提交并移动 HEAD,随后 index 与 HEAD 内容一致,因此 status 显示工作区干净(除非有新的工作区修改)。

从一道题,走向一组知识

把知识连起来

版本控制

Git 的 HEAD 是什么,进入 detached HEAD 状态后提交会发生什么、如何找回

同属「版本控制」专题,接着看 Git HEAD detached 游离 找回 在具体场景中的处理方式。

版本控制

为什么需要 Git 这样的分布式版本控制系统,它解决了本地备份和集中式 VCS 的哪些具体问题

同属「版本控制」专题,接着看 Git 分布式版本控制 优势 在具体场景中的处理方式。

参考资料

  • 2.2 Git Basics - Recording Changes to the Repository

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 三棵树的存储机制与流转命令
  3. 修改后只部分暂存再提交
  4. 文件类型的边界与未跟踪文件处理
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑