You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Git如何判断文件是已暂存(staged)还是已提交(committed)状态

Git 判定 index 中文件暂存/已提交状态的具体机制

首先纠正一个常见误解:Git 从来不会给 index(索引/暂存区)里的文件条目加「暂存」「已提交」的专属标记,git status 的判断完全基于多份基准数据的比对,没有单独的状态字段存这个属性。

先明确比对用到的三份基准数据:

  • HEAD 提交树:当前分支最新一次已提交的所有文件快照哈希集合,代表已经进仓库的正式版本
  • Index 文件:存储文件哈希、路径、创建/修改时间、文件大小等元数据的二进制文件,代表下一次提交的候选快照
  • 工作区文件:磁盘上当前你能直接编辑的实际文件

已提交(无变更)状态的判定规则

一个文件被判定为已提交、无修改,不会出现在变更列表里,需要同时满足两个条件:

  1. Index 中存储的该文件哈希值,和 HEAD 提交树里同路径文件的哈希值完全一致
  2. Index 中存储的该文件修改时间、文件大小等元数据,和当前工作区同路径文件的元数据完全一致

元数据比对是Git做的性能优化:如果每次跑git status都重新计算全量工作区文件的SHA1哈希,大仓库的执行速度会慢到没法用,只有元数据对不上的时候,Git才会重新读取文件内容算哈希,确认内容是不是真的发生了变更。

暂存状态的判定规则

只要 Index 中某文件的哈希值,和 HEAD 提交树里同路径文件的哈希值不一致,那么这两个哈希对应的内容差异,就属于已经暂存、会被下一次提交包含的内容,和当前工作区的文件状态无关。

这里要注意一个很容易混淆的场景:同一个文件可以同时存在暂存修改和未暂存修改。比如你改了a.txt之后执行git add a.txt,此时index里a.txt的哈希和HEAD不一样,这部分修改是暂存状态;如果你之后又改了a.txt但没有再次执行add,工作区的a.txt哈希会和index里的哈希不一致,这时候git status就会把a.txt同时列在「暂存的变更」和「未暂存的变更」两个分类下——前者是HEAD和Index的差异,后者是Index和工作区的差异。

所有状态的对应关系

其实git status展示的所有文件状态,本质都是两次diff的结果组合,和index条目本身带不带状态标签无关:

  • HEAD哈希 == Index哈希 == 工作区哈希:已提交,无变更
  • HEAD哈希 != Index哈希,Index哈希 == 工作区哈希:修改已暂存,待提交
  • HEAD哈希 == Index哈希,Index哈希 != 工作区哈希:修改未暂存
  • HEAD哈希 != Index哈希,Index哈希 != 工作区哈希:文件同时存在已暂存和未暂存的修改

还有个特殊场景:合并冲突时,index里会给同一个冲突路径存最多3份不同阶段的条目(分别对应合并共同祖先版本、当前分支版本、合并入分支版本),这类条目本身就是未完成合并的标识,自然不属于已提交状态。

内容的提问来源于stack exchange,提问作者lorem1213

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 17:15:41