?git运行原理
Git这个强大的版本
管理系统,工作的时候默默注视着你的代码目录,所有的操作几乎都在.git目录中完成。今天我们来做一次git的观众,以便深入了解git的各个操作。
首先,新建一个目录:git-monitor,进入目录后,用下面的命令初始化一个git仓库:
Bash代码
$> git init --bare git-monitor.git
$> git init --bare git-monitor.git
然后,创建一个工作目录wp1,意思为working_copy_1,进入该目录,运行git init,以创建.git目录。
进入.git目录,会发现下列文件和目录:
Bash代码
HEAD config description hooks/ info/ objects/ refs/
HEAD config description hooks/ info/ objects/ refs/
这些都是git的演员。我们当观众的,就从监控这些文件开始。但是演员分主角、配角,和跑龙套的,在这些文件中,config是配置文件,内容不会变的;hooks中的文件是一些回调程序的例子,删掉都没关系;description文件只为某些git的
web应用提供描述信息。它们都是跑龙套的,剩下的文件和目录有:
Bash代码
HEAD info/ objects/ refs/
HEAD info/ objects/ refs/
在后续的操作中,还有两位要上场,分别是index文件和logs目录,至此,主要演员表为:
Bash代码
HEAD index info/ objects/ refs/ logs/
HEAD index info/ objects/ refs/ logs/
要用肉眼盯着它们看,实在不容易,于是我写了个ruby小程序(下载链接在最后),用于监控这些目录,一旦目录和文件有变化,就在控制台上向我们
报告。我把这个
程序放到.git目录下,并把它跑起来。接下来,好戏就开演了。
回到wp1目录。新建一个文件file1.txt,然后看看监控程序,发现没有任何输出,说明git对刚才的操作没有响应。既然没反应,那我就接着操作,在file1.txt中加一行内容
File1.txt代码
content added by wp1, 1st time
content added by wp1, 1st time
再看看监控,还是没有反应。看来,只要我们不调用git命令,它就不会有反应。那我就调一个看看:
Bash代码
$> git add .
$> git add .
再看看监控,终于有反应了:
Bash代码
Created file: index (in dir: git-monitor/wp1/.git)
Created file: c2/a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc (in dir: git-monitor/wp1/.git/objects)
Created file: index (in dir: git-monitor/wp1/.git)
Created file: c2/a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc (in dir: git-monitor/wp1/.git/objects)
git add这个命令,根据`man git-add`的解释,是把某个文件加入到index。这个index实际上就是工作目录下文件和目录状态的一个快照(stage),每一次git提交所产生的tree对象,就是依据
index文件产生的(对index同志的详细采访,可以参考[url=progit.org/book /zh/ch9-2.html]这里[/url])。
我们来看看产生的那个object到底是什么,根据git的规则,object的目录名加文件名,和起来是一个40字符的字符串,它是对文件内容进行SHA1 digest之后,用16进制编码得到的结果。此文件的内容是二进制的,要查看它,就要用下面的命令:
Bash代码
$> git cat-file -t c2a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc
blob
$> git cat-file -p c2a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc
content added by wp1, 1st time
$> git cat-file -t c2a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc
blob
$> git cat-file -p c2a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc
content added by wp1, 1st time
其中,-t这个参数是为了显示object类型,-p这个参数,是为了显示object的内容。显然,这个object就是刚才加进去的file1.txt,它是一个blob类型的对象,只存储文件内容和长度。
接下来,我把这次添加的内容提交一下(git commit -m 'commit by wp1, 1st time'),再看看监控,又有输出了,这次的内容还真丰富啊:
Bash代码
Chang