在使用 git commit 保存项目版本(或“快照”)之前,你需要先告诉 Git 确切地要将哪些更改包含在该快照中。这个中间步骤是 Git 运作方式的核心,并能让你对项目历史有精细的控制。这个过程需要理解文件在 Git 中可能处于的三个主要状态:已修改、已暂存和已提交。这些状态对应于 Git 项目的三个主要区域:工作目录、暂存区(也称作“索引”)和Git 目录(仓库本身,存储在 .git 子文件夹中)。三个区域工作目录: 这是你的项目文件夹;你直接查看和编辑的文件都在这里。你在这里对文件做的任何更改最初都会相对于 Git 仓库中存储的最后一个快照被标记为已修改。把它想象成你的工作台,你正在那里积极地修改内容。暂存区(索引): 这是一个中间区域,可以看作是你下一次提交的“预览”。它包含关于下一次提交中将包含哪些内容的信息。当你暂存一个已修改的文件(通常使用 git add 命令)时,你就是将其当前状态添加到暂存区。这表示你打算将这些特定的更改包含在下一个保存点中。这就像把你要发货的物品放进一个特定的包装箱,与工作台上的其他物品分开。Git 目录(仓库): 这是 Git 存储项目元数据和对象数据库的地方,包括项目历史中所有已提交的快照。当你提交(使用 git commit 命令)时,Git 会获取暂存区中文件的当前状态,创建它们的永久快照,并将该快照存储在 Git 目录中。这类似于密封包装箱并将其移交,以便正式记录和发货。文件状态的生命周期我们来追踪一个文件如何通过这些状态:未跟踪: 当你在工作目录中首次创建一个文件时,Git 尚未知道它的存在。它是未跟踪的。已跟踪 / 未修改: 你将文件添加到 Git 的跟踪(例如,使用 git add 然后 git commit)。现在该文件被跟踪并被视为未修改,因为你的工作目录版本与 Git 仓库中最后一个快照的版本一致。已修改: 你在工作目录中编辑文件。Git 看到它与上次提交的版本不同,因此该文件现在是已修改状态。已暂存: 你对已修改的文件使用 git add 命令。这会将工作目录中文件的当前版本添加到暂存区。该文件现在被视为已暂存。请注意,工作目录中的文件没有改变;你只是将这个特定版本标记为下一次提交。暂存后,文件仍有可能再次被修改;在这种情况下,文件将同时处于已暂存状态(你添加的版本)和 已修改状态(工作目录中更新的更改)。已提交: 你使用 git commit 命令。Git 会获取暂存区中文件的快照,将其永久保存到 Git 目录历史中,暂存区中的文件现在被视为已提交。它们通常会恢复到未修改状态,假设工作目录版本与这个新提交的版本一致。与更简单的系统相比,这个工作流程可能看起来多了一个步骤,但暂存区是一个强大的功能。它能让你仔细地组织提交,将相关的更改分组为逻辑单元,即使你在工作目录中同时进行了其他不相关的更改。你可以精确地决定每个快照中包含什么。digraph G { rankdir=LR; node [shape=box, style=rounded, fontname="Arial", fontsize=10, margin=0.2]; edge [fontname="Arial", fontsize=9]; WORKDIR [label="工作目录\n(你编辑的文件)", color="#495057", style="filled, rounded", fillcolor="#f8f9fa"]; STAGING [label="暂存区(索引)\n(标记为下次提交的文件)", color="#1c7ed6", style="filled, rounded", fillcolor="#e7f5ff"]; REPO [label="Git 仓库 (.git)\n(已提交历史)", color="#37b24d", style="filled, rounded", fillcolor="#e6fcf5"]; WORKDIR -> STAGING [label=" git add <文件> ", color="#1c7ed6"]; STAGING -> REPO [label=" git commit ", color="#37b24d"]; REPO -> WORKDIR [label=" git checkout <文件> \n (或切换分支)", color="#495057", style=dashed]; WORKDIR -> WORKDIR [label="编辑文件\n(变为“已修改”)", pos="n,n", color="#f76707", constraint=false]; STAGING -> WORKDIR [label=" git reset HEAD <文件> \n ('取消暂存')", color="#1c7ed6", style=dashed]; { rank = same; WORKDIR; STAGING; REPO } } 工作目录、暂存区和 Git 仓库之间的关系,显示了在它们之间移动更改的命令。理解这种修改、暂存和提交的循环是 Git 有效使用的核心。你会经常使用 git status 等命令来查看你的文件处于什么状态。