Git的区域
# 1 概念
Git 与一般的版本控制工具有所不同, 在工作区和仓库区之间, 还有一个暂存区
- 什么是暂存区
- 暂存区的作用
什么是暂存区
暂存区是介于工作区和仓库区的一个区域. .git/index
就是暂存区
暂存区的作用
暂存区临时存放了一些修改, 比如写代码的过程中出现了灵感, 想记录下来, 但是又不想真正形成一次提交.
此时, 就可以保存到暂存区, 我的理解就是一个存放草稿的区域
为了搞清楚 Git 的暂存区, 我们先谈谈工作区
# 2 工作区
# 1) 概念
工作区: 顾名思义就是我们工作的区域
说人话, 就是我们写代码的地方, 可以看得到的地方
在工作区中, 每一个文件只有两种状态
- 未跟踪
- 已跟踪
- 未修改
- 已修改
- 已暂存
下图是文件状态的转换图, 出自: 记录每次更新到仓库 (opens new window)
对于刚创建的文件, 状态是未跟踪(untracked)
- 通过
git add
将文件添加到暂存区, 此时文件状态就变成 staged, 也就被 git 管理起来了 - 此时, 如果修改了文件, 状态变成
modified
, 然后可以再次通过add
命令添加到暂存区
# 3 暂存区
# 1) 什么是暂存区
有别于其他的 SCM(Source Code Management), 暂存区(index/stage)是 Git 特有的一个区域.
所在位置: .git/index
暂存区保存的什么
暂存区可以看作一个文件名到 blob 对象的索引表, 这也是为什么暂存区叫 index 的原因
大概样子如下
通过git ls-files -s
命令查看
文件权限 blob对象 文件名
通过这张索引表, 就可以清楚的知道
工作区中的文件hello.txt
对应 blob 对象4567
, 通过 blob 对象又可以找到压缩后的文件内容
# 2) 为什么要设计暂存区
杰哥一开始也非常不理解为什么要设计这样一个暂存区, 这样每次提交代码需要两步操作
- 先通过
git add
将工作区的内容先添加到暂存区 - 再通过
git commit
将暂存区的内容提交到本地仓库
直到杰哥接触到这个命令git add -i
, 交互式暂存.
我是这么理解的, 暂存区相当于购物车
, 而 commit 相当于支付. 有了购物车的好处是,
- 可以对购物车里的部分文件进行提交
- 可以对购物车里的文件进行管理, 比如从购物车中移除
进一步地说, 就是保证每次提交都是真正需要提交的内容, 在提交之前有一个地方(暂存区)可以随便造
# 4 仓库区
仓库区就是保存了不同版本的代码仓库
通过命令git commit
将 index 中的内容提交到仓库区.
后面我们会详细的分析每一个细节.
这里大家只需要知道
# 5 实操
实践出真知, 只有通过实践才能更好的理解
# 1) 命令
status 相关命令
# 对比工作区和暂存区的差异
git status
git status -s
2
3
- -s: 使用更简短的方式显示
- A: 添加到了暂存区
- M: 修改
- D: 删除
- ??: 未跟踪
查看暂存区命令
# 查看当前暂存区索引表
git ls-files
git ls-files -s
2
3
交互式暂存
# 交互式暂存
git add -i
2
每次执行git add
时, 会根据文件内容生成 blod 对象的 Hash 串
如果此时修改了文件内容. 可以看到工作区的状态从added
变成了modified
- hello git
+ hello git~
2
如果想找回上一次修改的内容. 可以通过
# 使用暂存区的内容覆盖工作区
git checkout -- hello.txt
2
但是这样, 最近一次的工作成果就没有了
如果添加到了暂存区, 这个时候 hello.txt 就会对应到新的 blob 对象4567
, 而之前的对象8d0e
就变成垃圾对象
垃圾对象
没有指向的对象
可以通过使用git prune
清理垃圾对象
# 清理垃圾对象(列出, 模拟)
git prune -n
# 清理垃圾对象
git prune
2
3
4