Git的使用---5. 工作区、暂存区和仓库
1. Git的提交流程
工作区
工作区就是你在电脑里能看到的目录,比如你的项目目录。
版本库
工作区下面有一个隐藏目录.git目录,这个.git目录不算工作区,它是Git的版本库,它存储变化日志及版本信息。
前面我们讲Git的基本使用的时候,我们提到了一个暂存区(stage, 或称为 index)的概念,当时怕大家被新概念吓怕,所以没有细细的讲,其实暂存区是Git最成功的设计之一,也是最难理解的部分,下面我们通过一个例子好好的分析学习一下暂存区。
当执行 "git status" 命令扫描工作区改动的时候,先依据.git/index文件中记录的已跟踪的文件的时间戳、长度等信息判断工作区文件是否改变。如果工作区的文件时间戳改变,说明文件的内容可能被改变了,这个时候就需要打开文件,读取文件内容,和更改前的记录的原始文件相比较,判断文件内容是否被更改。如果文件内容有改变,则将该文件新的时间戳记录到.git/index文件中。因此.git/index的时间戳也跟着变化了。为什么要这样做?因为判断文件是否更改,使用时间戳、文件长度等信息进行比较要比直接通过文件内容比较要快的多,所以Git这样的实现方式可以让工作区状态扫描速度更快。
下图展示了工作区、版本库中的暂存区和版本库之间的关系。
对上图的说明:
.git/index实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。在这个虚拟工作区的目录树中,记录了文件名、文件的状态信息(时间戳、文件长度等),文件的内容并不存储其中,而是保存在Git对象库(.git/objects)中,他们通过这个索引和对象实体是对应着的。从上面的图我们可以看出:
- 图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。
- 图中我们可以看出此时"HEAD"实际是指向master分支的一个“游标”。所以图示的命令中出现HEAD的地方可以用master来替换。
- 图中的 objects 标识的区域为Git的对象库,实际位于 ".git/objects" 目录下
- 当对工作区修改(或新增)的文件执行"git add"命令时,暂存区的目录树被更新。同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的id被记录在暂存区的文件索引中
- 当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
下面我们在过一遍流程:
【整体】Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
add后:
再执行git commit就可以一次性把暂存区的所有修改提交到分支
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的。
现在版本库变成了这样: