标签:
前一篇blog在实践过程有意无意地透漏了“暂存区”的概念。为了避免用户被新概念吓坏,在暂存区出现的地方又同时使用了“提交任务”这一更易理解的概念,但是暂存区(称为stage或index)才是其真正的名称。
在版本库 .git 目录下有一个index文件,下面针对这个文件做一个有趣的试验。具体操作步骤如下:
1. 首先执行 git checkout 命令(后面再介绍此命令),撤销工作区中 welcome.txt 文件尚未提交的修改。
$ git checkout -- welcome.txt $ git status -s
2. 通过状态输出可以看到工作区已经没有改动了。查看一下 .git/index 文件,注意该文件的时间戳为:2014-12-20 10:26:20
$ ls --full-time .git/index -rw-rw-r-- 1 fuhd fuhd 112 2014-12-20 10:26:20.550111224 +0800 .git/index
3. 现在更改一下welcome.txt的时间戳,但是不改变它的内容。然后再执行git status命令,查看.git/index文件的时间戳为:
2014-12-20 10:45:15
$ touch welcome.txt $ git status -s $ ls --full-time .git/index -rw-rw-r-- 1 fuhd fuhd 112 2014-12-20 10:45:15.550077688 +0800 .git/index
看到了吗?时间戳改变了!
这个试验说明当执行 git status 命令(或者 git diff 命令)扫描工作区改动的时候,先依据 .git/index 文件中记录的(用于跟踪工作区文件的)时间戳,长度等信息判断工作区文件是否改变,如果工作区文件的时间戳改变了,说明文件的内容可能被改变了,需要打开文件,读取文件内容,与更改前的原始文件相比较,判断文件内容是否被更改。如果文件内容没有改变,则将该文件新的时间戳记录到 .git/index 文件中。因为如果要判断文件是否更改,使用时间戳,文件长度等信息进行比较要比通过文件内容比较要快得多,所以Git这样的实现方式可以让工作区状态扫描更快速执行,这也是Git高效的原因之一。
文件.git/index 实际上就是一个包含文件索引的目录树,像是一个虚拟的工作区。在这个虚拟工作区的目录树中,记录了文件名和文件的状态信息(时间戳和文件长度等)。文件的内容并没有存储在其中,而是保存在Git对象库.git/objects目录中,文件索引建立了文件和对象库中对象实体之间的对应。下图展示了工作区,版本库中的暂存区和版本库之间的关系:
标签:
原文地址:http://my.oschina.net/fhd/blog/358300