3.1 status、add、commit:证据采集与归档


3.1 status、add、commit:证据采集与归档

本节摘要:高频三连的对象级还原。status 是两次比对的报告器,add 是采集入袋,commit 是盖章归档。本节还拆解 commit --amend 的真相、提交说明的写作纪律,以及删除与重命名在对象库里的真实形态。

先立两条纪律

  1. 能脱稿说出 status 各状态对应哪两次比对
  2. 能熟练使用 add 的各变体(-p、-u、-A、--intent-to-add)
  3. 能解释 --amend 与空提交的适用场景
  4. 能按规范写出可被工具链消费的提交说明

一、status:报告器,不是参与者

第 1 章已给出结论:status 只做两次比对(HEAD 的 tree 对 index、index 对工作区),不修改任何东西。这里补全它的常用侦察变体:

git status # 人话版,附下一步操作提示 git status -s # 紧凑版,两列状态码 git status --ignored # 连被忽略文件也列出 git status -sb # 附当前分支与领先落后计数(第4章详讲)

两列状态码的完整解码表值得贴在工位上:第一列是 HEAD 对 index(已暂存的变化),第二列是 index 对工作区(未暂存的变化)。M 修改、A 新增入袋、D 删除、?? 未追踪、R 重命名(仅 add 之后才可见)、U 冲突未解。R 的出现有个侦探细节:Git 是靠"删一个加一个、内容相似度够高"推断出重命名的,rename 检测有阈值,极端改写会退化成 D+A。重命名跟踪从来不是对象库的一等公民,这是很多"为什么 Git 没认出我重命名了"问题的答案。

二、add 的变体与选择

add 负责把工作区内容写成 blob 并登记进 index。变体按需选:

git add -p # 交互式挑代码块入袋(部分暂存) git add -u # 只更新已追踪文件 不引入新文件 git add -A # 工作区全部变化 git add --intent-to-add newfile # 先登记路径 内容稍后

--intent-to-add 冷门但好用:新文件先挂个名,之后 git add -p 就能对这个文件做部分暂存了(否则未追踪文件无法用 -p)。add 不做任何"提交",重复 add 只是更新 index 登记,对象库里可能多几个悬空 blob,无害。

一个团队协作的实际教训:某同事习惯 git add -A 一把梭,把本地调试配置 local.properties 提交进了主干,全组依次踩坑。两道防线:.gitignore 提前配置(治未追踪),code review 看清 status 输出再放行(治已入袋)。

三、commit:盖章的三种姿势

标准姿势之外,两种高频变体各有对象级真相:

git commit --amend 不是"修改上次提交"——提交不可变。它以当前 index 内容为基础新建一个提交(parent 是上上个提交),把分支指针挪过去,旧提交悬空。用途:提交后发现少 add 了一个文件、或说明写错,且该提交尚未推送时原地修正。若已推送再 amend,就撞上 2.3 的黄金法则,需要 force push 并惊动协作者。

git commit --allow-empty 建一个 tree 与 parent 完全相同的提交。看似无用,实则是打"里程碑刻度"的正规手段:发布流程里在主干上留一个空提交做标记,比标签更醒目地出现在普通 log 里。

git commit -a 等于"对所有已追踪文件先 add 再 commit",跳过 index 检查——便利与精细不可兼得,我个人在功能分支上用 -a,合入主干前的最后整理一定手工分袋。

提交说明的纪律不属于对象模型,但属于工程素养:首行不超过 50 字符、动词开头说清"做了什么",需要展开时空一行写正文,说"为什么这么做"。语义化前缀(feat、fix、docs、refactor 等)能让工具链自动生成变更日志,第 5 章的分支规范会与其配套。

四、删除与重命名的真相

git rm f.txt 做两件事:从工作区删文件、从 index 注销登记。只想要后者(保留工作区文件但停止追踪)用 git rm --cached——典型场景是把误提交的日志文件移出追踪再补 .gitignore。git rm 之后需 commit 才真正进入历史;在那之前 blob 仍在对象库里。

git mv a.txt b.txt 语义上等价于"mv 加 rm 加 add"三连,Git 甚至没有真正的重命名命令——它只是个便捷壳。理解这点后,"先改名后改内容"还是"先改内容后改名"会影响 rename 检测相似度,大重构时把重命名单独一个提交,diff 的可读性会好很多。

⚠️ 常见坑:git commit 时弹出编辑器写说明,慌乱中直接关掉导致提交被取消;或 -m 消息里带了引号导致 shell 解析出错。前者是正常机制(空说明即放弃),后者建议说明里避免嵌套引号。

还有一句直觉值得记牢:把"提交"当成不可变的公证记录——盖章前怎么改都行(index 随便调整),盖章后再改就是重写历史(amend/rebase),规则立刻切换。这条界线就是本地与公共的分界线。

状态码解码图

状态码解码图

本节要点回顾

  • status 只读:两次比对生成两列状态码,rename 是相似度推断不是登记。
  • add 变体:-p 精细分袋、-u 防- A 梭哈、--intent-to-add 配合 -p。
  • amend 是新建:未推送可放心用,已推送即触黄金法则。
  • 空提交有用:里程碑刻度的正规姿势。
  • rm/mv 是三连的壳:删除=工作区加 index 双动作,重命名靠检测。

证据已归档,下一节学习回看——log 与 diff 的考古工具全览。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U