核心概念
Git 的大部分命令,都是在工作区、暂存区和仓库这三个地方之间搬运数据。先把这几个概念弄清楚,后面的命令会好理解很多。
三个区域
一个 Git 项目包含三个主要区域:
工作区 暂存区 本地仓库
(Working Directory) (Staging Area) (Repository)
│ │ │
│ ── git add ──────▶ │ │
│ │ ── git commit ───▶ │
│ ◀──────────────── git restore / checkout ── │工作区(Working Directory)
工作区就是你在电脑上能看到的项目目录,是你编辑文件的地方。它是从仓库中取出的某个版本的文件。
暂存区(Staging Area / Index)
暂存区是一个文件(位于 .git/index),保存了下次将要提交的文件列表信息。可以把它理解为"提交前的购物车":你把想提交的修改放进去,确认无误后一起结账(提交)。
暂存区的存在,让你可以精细地控制每次提交包含哪些修改。例如你同时修改了三个文件,但只想先提交其中两个,就可以只把那两个加入暂存区。
本地仓库(Repository)
项目根目录下的 .git 目录就是本地仓库,Git 用它来保存项目的元数据和对象数据库。这是 Git 中最重要的部分,从其他计算机克隆仓库时,复制的就是这里的数据。
警告
不要手动修改或删除
.git目录中的内容,否则可能导致仓库损坏、历史丢失。
文件的状态
工作区中的每个文件只有两种大状态:已跟踪(tracked) 或 未跟踪(untracked)。已跟踪的文件是指已经被纳入版本控制的文件,它们又可以处于以下三种状态之一:
| 状态 | 含义 |
|---|---|
| 未修改(unmodified) | 文件与最近一次提交的内容相同 |
| 已修改(modified) | 修改了文件,但还没保存到暂存区 |
| 已暂存(staged) | 对已修改文件的当前版本做了标记,将包含在下次提交中 |
一个文件的典型生命周期是:
未跟踪 ──add──▶ 已暂存 ──commit──▶ 未修改 ──编辑──▶ 已修改 ──add──▶ 已暂存 ...基本的 Git 工作流程
- 在工作区中修改文件;
- 将你想要下次提交的更改选择性地暂存(
git add); - 提交更新,将暂存区的文件快照永久存储到 Git 仓库(
git commit)。
提交(Commit)
提交是 Git 中最基本的单元。每个提交包含:
- 项目在那一刻的完整快照;
- 作者、提交者和时间;
- 提交说明(commit message);
- 指向父提交的指针(第一个提交没有父提交,合并提交有多个父提交)。
每个提交都有一个唯一的 SHA-1 哈希值作为 ID,通常只需使用前 7 位即可引用,例如 a1b2c3d。
所有提交通过父指针连接起来,形成一条(或多条)历史链:
A ◀── B ◀── C ◀── D (main)分支(Branch)
Git 中的分支本质上只是一个指向某个提交的可移动指针。创建分支就是创建一个新指针,所以非常轻量,几乎瞬间完成。
E ◀── F (feature)
/
A ◀── B ◀── C ◀── D (main)HEAD
HEAD 是一个特殊的指针,指向你当前所在的分支(或提交)。当你切换分支时,HEAD 就会指向新的分支。每次提交后,HEAD 所指向的分支会自动前移到新提交。
# 查看 HEAD 当前指向
cat .git/HEAD
# ref: refs/heads/main当 HEAD 直接指向某个提交而不是分支时,称为**分离头指针(detached HEAD)**状态,此时的新提交不属于任何分支,切换走后容易"丢失"。
远程仓库(Remote)
远程仓库是托管在网络上(或其他位置)的项目版本库,例如 GitHub 上的仓库。你可以从远程拉取别人的提交,也可以把自己的提交推送上去。克隆的仓库默认有一个名为 origin 的远程仓库。
小结
- 工作区 是你编辑的地方,暂存区 是准备提交的内容,仓库 保存所有历史;
git add把修改从工作区放入暂存区,git commit把暂存区保存为一个新提交;- 分支 是指向提交的指针,HEAD 指向当前分支。
记住这张图,后面几乎所有命令都是在这三个区域之间移动数据。下一章我们来创建第一个仓库。