Skip to content初始化仓库:
查看文件状态:
添加文件到暂存区:
创建提交:
忽略文件:
Git 基本用法:文件跟踪与提交
概述
本章覆盖 Git 中最频繁的基础操作:初始化仓库、查看状态、将修改加入暂存区、创建提交以及配置忽略文件。掌握这四个命令(git init、git status、git add、git commit)便能够独立完成一个本地项目的版本记录。
工作区、暂存区与仓库
Git 将文件的流转划分在三个逻辑区域中:
- 工作区(Working Directory):当前在磁盘上可见的目录内容。新建、编辑文件时,所有变更首先发生在这里。
- 暂存区(Staging Area / Index):一份描述“下一次提交应该包含哪些文件快照”的清单。暂存区记录的是文件的完整快照状态,而不是差异。
- 仓库(Repository):
.git目录里存储的提交历史。每一次git commit都会生成一个包含作者、时间戳、提交说明及完整快照的提交对象,并通过父子关系形成历史链。
三个区域之间的关系不是固定的“修改 → 暂存 → 提交”流水线,而是一套选择机制:工作区的内容可以有选择地进入暂存区,再被提交。这构成了下文选择性暂存的基础。
文件状态生命周期
从 Git 的视角看,一个文件只会处于四种状态之一:
- 未跟踪(Untracked):文件存在于工作区但未被纳入版本控制。
- 已修改(Modified):文件已被跟踪,且工作区的内容与上一次提交的快照不一致,但尚未标记为下一次提交的内容。
- 已暂存(Staged):文件已修改并已显式地加入暂存区,下次提交将包含该版本。
- 已提交(Committed):文件已安全地存入仓库历史,工作区、暂存区与当前提交(HEAD)指向的快照保持一致。
状态流转示意:
untracked --[git add]--> staged
modified --[git add]--> staged
staged --[git commit]--> committed(工作区干净)
committed --[修改文件]--> modified同一文件可以同时处于“已修改但未暂存”和“已暂存但未提交”两种状态。例如,先执行一次 git add 将部分内容放入暂存区,之后继续编辑该文件,工作区里便有了新的修改。此时暂存区保存的仍是旧版本,工作区里则存着尚未暂存的新改动。这正是 git add -p 的应用场景。
初始化仓库:git init
在项目根目录执行 git init,Git 会创建 .git 隐藏目录,所有版本数据、暂存区元数据及配置都存放在其中。若目录下已存在 .git,再次执行 init 不会重置已有的提交历史,只会重新初始化模板文件。
bash
cd my-project
git init
# Initialized empty Git repository in /path/to/my-project/.git/此时仓库虽然建立,但工作区、暂存区、提交历史均为空。
查看文件状态:git status
git status 会列出三类信息:
- 已暂存的文件(Changes to be committed)
- 已修改但未暂存的文件(Changes not staged for commit)
- 未跟踪的文件(Untracked files)
刚初始化后的仓库:
bash
$ git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)新建一个文件后再查看:
bash
$ echo "# my-project" > README.md
$ git status
On branch main
No commits yet
Untracked 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 add
git add 的行为因文件当前状态而不同:
- 对新文件(未跟踪):
git add <file>将其转为已暂存,Git 开始跟踪该文件。 - 对已跟踪文件(已修改):
git add <file>将工作区中的最新内容更新至暂存区。 git add .会递归地暂存当前目录下所有新建和修改过的文件(包括子目录中未被跟踪的新文件),但不会暂存已删除的文件。要一并暂存删除操作,可以使用git add -A。
常用形式:
bash
# 暂存单个文件
git add src/main.ts
# 暂存当前目录所有变更(不包括删除)
git add .
# 交互式部分暂存
git add -p src/main.ts如果执行 git add 后又修改了同一文件,工作区与暂存区之间便会产生差异。git status 会同时显示该文件既“已暂存”又“已修改未暂存”。此时若需要将新修改也纳入暂存区,必须再次执行 git add。
选择性暂存
借助暂存区的清单特性,一个文件的修改可以被拆分为多次提交,一次提交也可以只包含一组相关文件的子集。例如,在同一个源文件里修复了一个 bug 并顺便调整了日志输出,若希望这两件事分别进入不同的提交节点,可使用:
bash
git add -p index.ts-p 选项会逐块(hunk)询问该文件的修改是否需要暂存。回答 y 即纳入本次提交,回答 n 则跳过。这样暂存区里只包含选中的修改,工作区仍保留着完整的改动。提交之后,剩余修改仍然是“已修改未暂存”状态,可供后续另行组织提交。
如果不使用选择性暂存而直接执行 git add index.ts,文件的全部当前内容会被放入暂存区,无法再做提交级粒度的拆分。
创建提交:git commit
git commit 将暂存区的内容生成一个快照,作为新的提交对象存入仓库。提交时必须附带一条提交信息。
最简方式是通过 -m 参数直接给出信息:
bash
git commit -m "Initialize project structure"省略 -m 会启动默认编辑器,以便编写更详细的提交说明。详细的提交信息在日后回溯历史时可提供清晰的线索。常见格式为:
简短摘要(建议不超过 50 字符)
详细描述改动原因、背景及影响范围,使用现在时祈使句。例如:
Add TypeScript configuration
Set up tsconfig.json with strict mode and ES2020 target.
This is the base configuration before adding any source code.git commit 还提供 -a 选项,该选项会自动暂存所有已跟踪文件的修改并提交,省去单独执行 git add 的步骤。但它不会包含未跟踪的文件,新文件仍然需要显式 git add。
提交完成后,git status 会报告工作区与暂存区均干净——工作区、暂存区与 HEAD 指向的快照三者一致。可通过以下命令验证各区域之间的差异:
bash
# 工作区 vs 暂存区
git diff
# 暂存区 vs 最新提交
git diff --cached
# 工作区 vs 最新提交
git diff HEAD刚提交后,这三个命令均不会有输出。
示例:从新建文件到首次提交
以下是一个从零开始到完成首次提交的完整流程:
bash
# 1. 初始化
mkdir demo && cd demo
git init
# 2. 创建文件
echo 'console.log("hello");' > index.ts
# 3. 查看状态
git status
# Untracked files: index.ts
# 4. 加入暂存区
git add index.ts
git status
# Changes to be committed: new file: index.ts
# 5. 首次提交
git commit -m "Add entry point"
# 6. 确认干净状态
git status
# nothing to commit, working tree clean此时仓库中已包含一次提交记录,可使用 git log 查看。
忽略文件:.gitignore
项目中的编译产物、依赖目录、本地配置文件等通常不应纳入版本控制。.gitignore 文件用于声明忽略规则,每行一条:
node_modules/
dist/
.env
*.log常用规则说明:
- 以
/结尾表示只匹配目录。 *匹配任意字符(/除外)。!开头表示取反,可强制跟踪曾被忽略的文件(如!.gitkeep)。- 子目录下的
.gitignore仅对其所在目录及子目录生效。
.gitignore 只对未跟踪的文件有效。如果某个文件已被纳入版本控制,即使随后将其写入忽略列表,Git 仍会继续跟踪其变更。要停止跟踪,需先执行 git rm --cached <file> 并在新提交中移除该文件。
注意点
git add . 的范围
全量暂存虽然便捷,但容易将不相关的改动混入同一个提交。在多人协作仓库或存在多项独立修改时,建议先通过 git status 确认改动列表,再针对性地添加具体文件,或使用 git add -p 进行精细控制。
暂存区不会自动刷新
执行 git add 之后再次修改同一文件,暂存区中保存的仍然是旧版本。git status 会标记该文件同时存在于 staged 和 modified 两个区域,此时需要重新执行 git add 以更新暂存区。
提交信息的可读性
避免使用无意义的 "update"、"fix bug" 等提交信息。每次提交的信息应是未来阅读历史时能直接理解的一句话,它是代码审查和问题定位的基本线索。
.gitignore 对已跟踪文件无效
修改 .gitignore 后发现某个已跟踪文件的变更仍会出现,这属于预期行为,需要通过 git rm --cached 将其从版本控制中移除。
