跳转至

P2-14.1 Git 是管理变更历史的工具

Section ID: P2-14.1 Version: v2026.07.20

在 Part 2 Chapter 13,我们用 Matplotlib 制作图表,并把输出图片链接进文档。问题也就在这里立刻出现了。如果文档、代码、图片、调查笔记一起变化,过一段时间后就很难再记清“到底改了什么,为什么改”。

Git 就是用来记录这种变化的工具。它不只是保存代码的工具,更适合被理解为:在学习过程中追踪文档与示例代码如何变化的装置。你需要先建立这种感觉,这样到了 Part 3,即使在 baseline 比较、预处理修改、评价指标解释这类实验条件经常变化的场景里,也还能重新说明 改了什么,为什么改

本节说明 Git版本控制(version control)提交(commit)暂存区(staging area)仓库(repository) 的基本区分。如果说 Chapter 11 到 13 是通过数组、表格、图表来读取和确认数据的阶段,那么这里的问题就变成:要如何把这些计算与确认过程留下来,作为一组组变更。Git 不是一个突然冒出来的工具,而应该被读成:能让你在 Part 3 再次解释 baseline 比较、预处理修改、metric 解读的记录工具。后面继续到分支与部署时,也请把概念词汇表一起当作基准点。

核心判断标准:Git 是管理变更历史的工具

  • 能把版本控制解释为“在时间过去之后,仍然能重新找到某个过去状态的记录”。
  • 能把 Git 的提交(commit)理解为“有意义的变更组合”,而不是单纯保存文件。
  • 能直观说明工作目录(working tree)、暂存区(staging area)、仓库(repository)之间的差别。
  • 能区分 git statusgit addgit commitgit log 的作用。
  • 能说明为什么学习文档和示例代码应该用 Git 来管理。

三个判断标准

标准 为什么重要 本节需要达到的理解程度
Git 留下的是什么? 它帮助你区分“保存文件”和“记录变更历史”。 理解它记录的是变更历史与说明,而不只是文件本身。
为什么 addcommit 要分开? 它明确区分“选择变更”和“确认记录”是两件不同的事。 理解“决定要归成一组什么变更”和“给这组变更命名”是不同动作。
为什么连文档工作也重要? 它帮助你把代码之外的产物也读成同一组变更单位。 理解它会让你更容易回头解释什么时候、改了什么、为什么改。
术语 本节先抓住的含义
Git 记录变更历史与说明,而不只是文件本身的版本控制工具。
版本控制(version control) 一种记录方式,让你重新找回文件状态如何随时间变化、又为什么变化。
提交(commit) 在仓库历史中留下一个有意义变更组合的记录单位。
暂存区(staging area) 你为这次提交挑选变更时所经过的中间空间。
仓库(repository) 积累提交历史的 Git 记录空间。

保存文件和留下变更历史并不是一回事

保存文件后,当前状态会被留下。但它不会自动说明:前一个状态为什么变了,哪些文件是一起变的。

例如,假设你做了下面这些工作。

  • 写了一节正文草稿。
  • 添加了一个生成图表的脚本。
  • 生成了两张输出图片。
  • 修改了网站目录配置。

这四件事看起来像是分散的任务,但实际上它们可能构成同一个有意义的变更组合:把某一节中的图表说明及其关联资源一起反映进去

Git 会把这样的组合记录为一个提交(commit)。

版本控制与其说是“回退”,不如说是“解释”

刚开始学 Git 时,人很容易把它理解成“犯错时可以退回去的工具”。这种说法也没错。但在这里,我们把它看得更宽一些。

版本控制(version control)是为了在时间过去之后回答下面这些问题的装置。

  • 哪些文件改了?
  • 为什么改?
  • 哪些文件是一起改的?
  • 某个说明是什么时候进入项目的?
  • 如果出现问题,是从哪一次变更之后开始出现的?

Git 官方书把版本控制解释为:一种能随着时间记录文件变化,并允许你以后再找回特定版本的系统。在这里,我们把这个视角应用到文档写作与学习记录上。

Git 的基本流程

这里把 Git 的流程分成下面三个空间来看。

flowchart TD
  A["工作区<br/>当前编辑文件的地方"]
  B["暂存区<br/>挑选本次记录所含变更的地方"]
  C["仓库<br/>以 commit 形式保存的历史"]

  A -->|"git add"| B
  B -->|"git commit"| C
  C -->|"用 git log 查看"| C

这个流程里最重要的一点是:保存提交并不相同。

保存文件,是在编辑器里把当前文件内容写入磁盘。提交,则是把这些已保存的变更中“有意义的一组”记录进仓库历史。

git status 是询问当前状态的命令

做 Git 工作时,通常最先看的命令是 git status

git status

这个命令回答的是下面这些问题。

  • 哪些文件被修改了?
  • 是否出现了新文件?
  • 有没有已经被选入这次提交的文件?
  • 当前分支(branch)是什么?

这里可以把 git status 理解成“询问现在这个工作现场是什么状态的命令”。

git add 是挑选文件的动作

git add 并不表示文件会立刻被永久保存。它表示:把应该纳入这次提交的变更放进暂存区(staging area)。

git add docs/chapter-14/section-01.md

这里的关键是“挑选要进入这次记录的变更”。即使有很多文件变了,也不一定要全部放进一个提交里。如果它们的目的不同,分开提交会让以后更容易读。

例如,下面两类工作最好尽量分开记录。

变更 为什么应该分开提交
编写 Chapter 14 正文 目的在于补充书的内容
修改 CSS 布局 目的在于改善界面显示

如果把这两类变化放进同一个提交,之后就更难追踪“为什么这个 CSS 被改了”。

git commit 是给一组变更起名字

git commit 会把暂存的变更留进仓库历史中。

git commit -m "docs(part2): add git version control introduction"

提交信息(commit message)不只是备忘。它是一个标题,用来告诉之后阅读历史的人“这次变更到底是什么”。

好的提交信息通常满足下面这些条件。

  • 能看出改了什么。
  • 避免过于宽泛的表达。
  • 比起只写文件名,更能表现变更目的。
  • 之后在 git log 中再读时,依然有意义。

下面是一个不好的例子。

git commit -m "update"

这个信息没有说明到底更新了什么。

git log 是读取变更历史的命令

当提交积累起来后,可以用 git log 来查看历史。

git log --oneline

这个命令会简短显示提交列表。这里可以把它理解成“查看这个项目是按什么顺序变化过来的列表”。

在学习文档项目里,git log 能帮助回答下面这些问题。

  • 这一节是什么时候加进去的?
  • 目录是在第几个提交里改动的?
  • 某张图片文件是和哪篇正文一起加入的?
  • 部署之前都进来了哪些变更?

为什么 Git 在文档项目中也重要

文档项目不只是“完成后的文档”,而是学习过程的结果。正文、调查笔记、示例代码、图片、部署配置都会一起变化。尤其到了 Part 3,即使面对同样的数据,预处理、baseline、threshold、评价表也会开始一起变化。从这个意义上说,Git 更像是实验比较记录,而不是最终答案存放柜

Git 能让你留下下面这些关系。

产物 用 Git 可以留下的问题
正文 Markdown 某个说明是什么时候加进去的?
调查笔记 依据了哪些资料?
示例代码 它生成了哪张输出图片?
图片文件 它和哪段代码或哪一节相关?
网站导航设置 哪个文档进入了公开目录?

从这个视角看,Git 并不只是开发者的工具。随着文档变多、依据变多、练习代码变多,Git 就会成为管理学习变更历史的工具。

使用 Git 时的最小习惯

一开始并不需要知道所有 Git 命令。在同时处理文档和练习示例的项目里,哪怕只有下面这些习惯,也会有很大帮助。

  1. 在工作前后都用 git status 查看状态。
  2. 一个提交只放一个目的明确的变更。
  3. 在提交信息里写出变更目的。
  4. 一起确认生成文件和源文件之间的关系。
  5. 把修改部署设置的工作和写正文的工作分开。

这些习惯会在 P2-14.2 学习分支(branch)、写作分支与部署分支流程时再次用到。

用案例来看

案例 1. 当正文和图片在同一天一起变动时,该怎么解释?

假设一位文档作者修改了一节正文,同时也一起改了示例代码,还把由这段代码重新生成的图表图片也换掉了。人在脑中会知道这还是同一项工作,但几天之后就可能逐渐模糊:这些文件为什么会一起改?

这时,Git 发挥的作用就不是简单存储,而是把变更理由打包成记录。如果正文 Markdown、图片生成代码、输出图片、目录修改都属于同一个目的,也就是加强图表说明,那么这个目的就可以连同提交信息一起留下。

这个案例也说明了为什么 git addgit commit 要分开。你得先挑出哪些变更属于这次记录,再给这组变更起名字并留进历史里。只有这样,之后才能解释 到底改了什么,为什么改

也就是说,Git 入门里真正重要的,不是死记很多命令,而是培养“把变更归成有意义说明单位”的感觉。只有有了这种感觉,在文档、代码、图片一起移动的项目里,历史才会是可读的。

检查清单

  • 能说明“保存文件”和“做一次 Git 提交”之间的区别吗?
  • 能区分工作目录、暂存区和仓库吗?
  • 能说出 git statusgit addgit commitgit log 的作用吗?
  • 能说明为什么一个提交应该只承载一个目的吗?
  • 能说明为什么在文档项目里,Git 需要被当作学习记录管理工具吗?
  • 能说明 Git 是管理变更历史的工具,而提交能帮助追踪正文、代码、图片和调查笔记之间的连接。

来源与参考资料

  • Scott Chacon and Ben Straub, Pro Git 2nd Edition: About Version Control, Git documentation, 确认日期:2026-07-20. https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control 这是把版本控制说明为随时间记录文件变化并可恢复特定版本的依据。
  • Git project, git-status Documentation, 确认日期:2026-07-20. https://git-scm.com/docs/git-status 这是说明 git status 会显示工作树、索引和未跟踪文件状态的直接参考资料。
  • Git project, git-commit Documentation, 确认日期:2026-07-20. https://git-scm.com/docs/git-commit 这是说明 git commit 会把索引中的当前内容连同日志消息记录为新提交的直接参考资料。