Git 工作区、暂存区和版本库
本章将深入探讨 Git 的三个核心概念:工作区、暂存区和版本库。理解这三个区域的作用和相互关系是掌握 Git 的关键。
三个区域概览
┌─────────────────────────────────────────────────────────────────┐
│ Git 项目结构 │
├─────────────────────────────────────────────────────────────────┤
│ 工作区 (Working Directory) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 实际的项目文件 │ │
│ │ • 可以编辑、创建、删除文件 │ │
│ │ • Git 监控但不直接管理 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ git add │
│ ↓ │
│ 暂存区 (Staging Area / Index) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 临时存储即将提交的文件快照 │ │
│ │ • 精确控制提交内容 │ │
│ │ • 位于 .git/index 文件中 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ git commit │
│ ↓ │
│ 版本库 (Repository) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 存储完整的项目历史 │ │
│ │ • 包含所有提交、分支、标签 │ │
│ │ • 位于 .git 目录中 │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘工作区 (Working Directory)
定义和特点
工作区是你实际工作的地方,包含项目的所有文件和文件夹(除了 .git 目录)。
特点:
- 📁 包含项目的实际文件
- ✏️ 可以自由编辑、创建、删除文件
- 👀 Git 会监控文件变化但不自动保存
- 🔄 可以随时恢复到任何历史版本
工作区操作示例
bash
# 创建演示项目
mkdir git-areas-demo
cd git-areas-demo
git init
# 在工作区创建文件
echo "# 项目说明" > README.md
echo "print('Hello, World!')" > main.py
mkdir src
echo "# 工具函数" > src/utils.py
# 查看工作区状态
git status输出:
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
main.py
src/
nothing added to commit but untracked files present (use "git add" to track)工作区文件状态
工作区中的文件可能处于以下状态:
- 未跟踪 (Untracked):新创建的文件
- 已修改 (Modified):已跟踪但被修改的文件
- 已删除 (Deleted):被删除的已跟踪文件
bash
# 演示不同状态
git add README.md main.py src/utils.py
git commit -m "初始提交"
# 修改已跟踪文件
echo "更新内容" >> README.md
# 创建新文件
echo "新功能" > feature.py
# 删除文件
rm main.py
# 查看状态
git status输出:
On branch main
Changes 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: README.md
deleted: main.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
feature.py
no changes added to commit (use "git add" or "git commit -a")暂存区 (Staging Area)
定义和特点
暂存区(也称为索引 Index)是工作区和版本库之间的缓冲区,用于准备下次提交的内容。
特点:
- 🎯 精确控制提交内容
- 📦 可以部分暂存文件修改
- 🔄 可以多次修改暂存内容
- 💾 存储在
.git/index文件中
暂存区操作
1. 添加文件到暂存区
bash
# 添加单个文件
git add README.md
# 添加多个文件
git add main.py feature.py
# 添加目录
git add src/
# 添加所有修改
git add .
# 添加所有已跟踪文件的修改
git add -u
# 交互式添加
git add -i2. 查看暂存区内容
bash
# 查看暂存区状态
git status
# 查看暂存区与工作区的差异
git diff
# 查看暂存区与上次提交的差异
git diff --staged
# 或
git diff --cached3. 从暂存区移除文件
bash
# 从暂存区移除文件(保留工作区修改)
git restore --staged README.md
# 或使用旧语法
git reset HEAD README.md
# 移除所有暂存的修改
git restore --staged .部分暂存功能
Git 允许你只暂存文件的部分修改:
bash
# 创建一个文件进行演示
cat > example.py << EOF
def function1():
print("第一个函数")
def function2():
print("第二个函数")
def function3():
print("第三个函数")
EOF
git add example.py
git commit -m "添加示例函数"
# 修改多个函数
cat > example.py << EOF
def function1():
print("第一个函数 - 已更新")
return "updated"
def function2():
print("第二个函数")
def function3():
print("第三个函数 - 已更新")
return "updated"
EOF
# 交互式部分暂存
git add -p example.pyGit 会逐个显示修改块,你可以选择:
y- 暂存这个修改块n- 不暂存这个修改块s- 分割修改块q- 退出
版本库 (Repository)
定义和特点
版本库是 Git 存储项目完整历史的地方,包含所有提交、分支、标签等信息。
特点:
- 📚 存储完整的项目历史
- 🌳 管理分支和标签
- 🔒 数据完整性保证
- 📁 位于
.git目录中
版本库结构
bash
# 查看 .git 目录结构
ls -la .git/主要文件和目录:
.git/
├── HEAD # 指向当前分支
├── config # 仓库配置
├── description # 仓库描述
├── index # 暂存区文件
├── hooks/ # Git 钩子脚本
├── info/ # 排除文件等信息
├── objects/ # Git 对象存储
├── refs/ # 引用存储(分支、标签)
└── logs/ # 引用日志版本库操作
1. 提交到版本库
bash
# 提交暂存区内容
git commit -m "提交信息"
# 提交并添加所有已跟踪文件的修改
git commit -am "提交信息"
# 修改最后一次提交
git commit --amend -m "新的提交信息"2. 查看版本库历史
bash
# 查看提交历史
git log
# 简洁格式
git log --oneline
# 图形化显示
git log --graph --oneline
# 查看特定文件的历史
git log -- filename
# 查看提交统计
git log --stat3. 查看版本库对象
bash
# 查看对象类型
git cat-file -t HEAD
# 查看对象内容
git cat-file -p HEAD
# 查看树对象
git ls-tree HEAD三个区域的交互
数据流向图
工作区 ←──────────────────────────────────────────────────────→ 版本库
│ ↑
│ git add │
↓ │ git checkout
暂存区 ──────────────────→ 版本库 │
git commit │
│
工作区 ←──────────────────────────────────────────────────────┘常用操作命令
1. 工作区 → 暂存区
bash
git add <file> # 添加文件
git add . # 添加所有文件
git add -A # 添加所有修改(包括删除)
git add -u # 添加已跟踪文件的修改
git add -p # 交互式添加2. 暂存区 → 版本库
bash
git commit -m "message" # 提交暂存区内容
git commit --amend # 修改最后一次提交3. 版本库 → 工作区
bash
git checkout <commit> -- <file> # 恢复文件到特定版本
git restore <file> # 恢复文件到最新提交版本
git reset --hard <commit> # 重置到特定提交(危险操作)4. 暂存区 → 工作区
bash
git restore --staged <file> # 取消暂存
git reset HEAD <file> # 取消暂存(旧语法)实际应用场景
场景1:精确控制提交内容
bash
# 同时修改了多个文件,但只想提交部分修改
echo "功能A的修改" >> fileA.txt
echo "功能B的修改" >> fileB.txt
echo "临时调试代码" >> debug.txt
# 只提交功能相关的修改
git add fileA.txt fileB.txt
git commit -m "实现功能A和功能B"
# debug.txt 保留在工作区,不提交场景2:分阶段开发
bash
# 第一阶段:实现基本功能
echo "基本功能实现" > feature.py
git add feature.py
git commit -m "实现基本功能"
# 第二阶段:添加错误处理
echo "添加错误处理" >> feature.py
git add feature.py
git commit -m "添加错误处理"
# 第三阶段:优化性能
echo "性能优化" >> feature.py
git add feature.py
git commit -m "优化性能"场景3:实验性修改
bash
# 在工作区进行实验性修改
echo "实验性功能" > experiment.py
# 如果实验成功,添加到暂存区
git add experiment.py
# 如果实验失败,直接丢弃
rm experiment.py
# 或者
git clean -f高级技巧
1. 暂存区的高级用法
bash
# 查看暂存区的具体内容
git ls-files --stage
# 比较工作区、暂存区、版本库
git diff # 工作区 vs 暂存区
git diff --staged # 暂存区 vs 版本库
git diff HEAD # 工作区 vs 版本库2. 工作区的清理
bash
# 查看未跟踪的文件
git clean -n
# 删除未跟踪的文件
git clean -f
# 删除未跟踪的文件和目录
git clean -fd
# 交互式清理
git clean -i3. 版本库的维护
bash
# 垃圾回收
git gc
# 检查仓库完整性
git fsck
# 查看仓库大小
du -sh .git/常见问题和解决方案
问题1:暂存区和工作区不一致
bash
# 问题:修改了文件但忘记添加到暂存区
echo "新修改" >> file.txt
git commit -m "提交修改" # 这不会包含新修改
# 解决:添加修改并修正提交
git add file.txt
git commit --amend --no-edit问题2:误删了工作区文件
bash
# 恢复已跟踪的文件
git restore deleted_file.txt
# 恢复到特定版本
git restore --source=HEAD~1 file.txt问题3:暂存区内容错误
bash
# 清空暂存区
git restore --staged .
# 重新选择要暂存的内容
git add correct_file.txt最佳实践
1. 工作区管理
- ✅ 保持工作区整洁,及时清理临时文件
- ✅ 使用
.gitignore忽略不需要跟踪的文件 - ✅ 定期检查
git status
2. 暂存区使用
- ✅ 使用暂存区精确控制提交内容
- ✅ 利用
git add -p进行部分暂存 - ✅ 提交前检查
git diff --staged
3. 版本库维护
- ✅ 写清晰的提交信息
- ✅ 保持提交的原子性(一个提交只做一件事)
- ✅ 定期进行垃圾回收
总结
理解工作区、暂存区和版本库的关系是掌握 Git 的关键:
- 工作区:你的工作空间,自由编辑文件
- 暂存区:提交的准备区,精确控制提交内容
- 版本库:永久存储,保存完整的项目历史
掌握这三个概念后,你就能:
- ✅ 精确控制每次提交的内容
- ✅ 安全地进行实验性修改
- ✅ 有效管理项目的版本历史
- ✅ 理解 Git 命令的真正含义
在下一章中,我们将学习如何创建和管理 Git 仓库。