记录更新到仓库
你现在已经拥有了一个真正的 Git 仓库,并从其中检出了文件的某个版本。接下来,你需要对这些文件做些修改,在完成一个阶段的目标后,提交本次更新到仓库。
在开始操作之前,彻底理解 Git 如何管理文件的状态是至关重要的。这是 Git 学习曲线中最陡峭的一段,但一旦掌握,你将如鱼得水。
文件的生命周期
Section titled “文件的生命周期”工作目录下的每一个文件都不外乎这两种状态:已跟踪(Tracked) 或 未跟踪(Untracked)。
- 已跟踪(Tracked):指那些 Git 已经知道的文件(已提交或已暂存)。它们又可以分为三种子状态:
- 未修改(Unmodified):自上次提交后未曾改动。
- 已修改(Modified):自上次提交后被修改了,但还没放到暂存区。
- 已暂存(Staged):修改已放入暂存区,准备下次提交。
- 未跟踪(Untracked):Git 尚未管理的任何文件(既没有在上次提交中,也没有在暂存区中)。
下图展示了文件的生命周期流转:
graph LR Untracked((未跟踪)) -- "git add" --> Staged Unmodified((未修改)) -- 编辑文件 --> Modified((已修改)) Modified -- "git add" --> Staged((已暂存)) Staged -- "git commit" --> Unmodified Unmodified -- "git rm" --> StagedDel((已暂存删除))
%% 定义适配亮/暗模式的样式类 classDef untrackedNode fill:#718096,stroke:#4a5568,color:#fff,stroke-width:2px classDef unmodifiedNode fill:#4a5568,stroke:#2d3748,color:#fff,stroke-width:2px classDef modifiedNode fill:#e53e3e,stroke:#c53030,color:#fff,stroke-width:2px classDef stagedNode fill:#3182ce,stroke:#2c5282,color:#fff,stroke-width:2px
class Untracked untrackedNode class Unmodified unmodifiedNode class Modified modifiedNode class Staged stagedNode核心概念:三个区域
Section titled “核心概念:三个区域”理解了状态,我们再来看看这些状态对应的物理/逻辑区域。这是 Git 最核心的设计之一。
-
工作区 (Working Directory): 就是你在电脑文件资源管理器里能看到的目录。你在这里编辑代码、修改文件。这里是“现实世界”。
-
暂存区 (Staging Area / Index): 这是一个逻辑区域(实际上是
.git目录下的一个文件)。这是 Git 最让新手困惑的地方。或者用照相来比喻:
- 工作区:大家在自由活动。
- 暂存区:摄影师说“来,大家站好位置,整理表情”,大家走上舞台摆好姿势(Stage 也有舞台的意思)。
- 仓库:摄影师按下快门,照片(Snapshot)生成并存入相册。
-
仓库 (Repository):
.git目录,用于存储项目的元数据和对象数据库。
检查当前文件状态
Section titled “检查当前文件状态”要查看哪些文件处于什么状态,主要的工具是 git status 命令。
1. 干净的工作区
Section titled “1. 干净的工作区”如果你的工作区所有文件都已提交,且没有新文件,运行 git status 会看到:
$ git statusOn branch mainnothing to commit, working tree clean这意味着目前很“干净”,没有东西需要 Git 操心。
2. 发现新文件 (Untracked)
Section titled “2. 发现新文件 (Untracked)”如果你创建了一个新文件 README.md,它首先是未跟踪的:
$ echo "My Project" > README.md$ git statusOn branch mainUntracked files: (use "git add <file>..." to include in what will be committed) README.md
nothing added to commit but untracked files present (use "git add" to track)Git 明确告诉你 README.md 是 Untracked files。除非你显式告诉 Git,否则它不会把这个文件纳入版本控制。
3. 已暂存状态 (Staged)
Section titled “3. 已暂存状态 (Staged)”如果你运行 git add README.md,此时文件就进入了暂存区:
$ git add README.md$ git statusOn branch mainChanges to be committed: (use "git restore --staged <file>..." to unstage) new file: README.mdChanges to be committed 下的文件,就是如果你现在运行 git commit,会被记录到历史中的内容。
4. 已修改状态 (Modified)
Section titled “4. 已修改状态 (Modified)”假设你还有一个叫 CONTRIBUTING.md 的文件之前已经被跟踪了,现在你修改了它:
$ git statusOn branch mainChanges not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: CONTRIBUTING.mdChanges not staged for commit 说明文件被修改了,但还没有放入暂存区(还没有上舞台/放入购物车)。如果现在提交,这个修改不会被记录。
状态简览 (git status -s)
Section titled “状态简览 (git status -s)”当文件变多时,git status 的输出会非常长。Git 提供了一个紧凑的格式:
$ git status -s M README.mdMM RakefileA lib/git.rbM lib/simplegit.rb?? LICENSE.txt这里的输出分为两列(左列和右列),含义如下:
| 符号 | 含义 |
|---|---|
?? | 新文件,未跟踪 (Untracked) |
A | 新文件,已暂存 (Added to Staging) |
M | 已修改,未暂存 (Modified in Working Dir) |
M | 已修改,已暂存 (Modified in Staging) |
MM | 由你来猜? |
关于 MM 的解释:
这意味着该文件在工作区被修改并暂存了(左边的 M),然后又在工作区被修改了(右边的 M)。
这在实际开发中很常见:你写了一半代码觉得不错,先 git add 了一下(存个档),然后继续写,还没再次 add。此时这个文件既有已暂存的内容,也有未暂存的内容。