c3a918d
tree 30c64c3a55b02f4c251565ef057d402f84751b56
author Kevin Fu
1281230735 +0800
committer Kevin Fu 1281230735 +0800
commit by wp1, 1st time
$> git cat-file -p 30c64c3a55b02f4c251565ef057d402f84751b56
100644 blob c2a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc file1.txt
$> git cat-file -p 1671ae856c149673436da08f1ba026469c3a918d
tree 30c64c3a55b02f4c251565ef057d402f84751b56
author Kevin Fu 1281230735 +0800
committer Kevin Fu ace@email> 1281230735 +0800
commit by wp1, 1st time
$> git cat-file -p 30c64c3a55b02f4c251565ef057d402f84751b56
100644 blob c2a04aa8cba9ba9a7a2fb8c9ecf74a3a0fc5e3fc file1.txt
显然,第一个文件是个commit对象,第二个文件是个tree对象,从引用关系来看,是先生成的tree对象,再生成的commit对象。注意,这个commit对象没有parent引用。
再看看后面生成的refs,用git show-refs可以查看所有refs的内容
Bash代码
$> git show-refs
1671ae856c149673436da08f1ba026469c3a918d refs/heads/master
$> git show-refs
1671ae856c149673436da08f1ba026469c3a918d refs/heads/master
master当然指的是master分支,它的值指向刚才看到的commit对象
最后就是两个log文件。log文件虽然只是供人查看,但在git中的地位非同一般。先看看其内容:
Bash代码
$ cat logs/HEAD
0000000000000000000000000000000000000000 1671ae856c149673436da08f1ba026469c3a918d Kevin Fu 1281230735 +0800 commit (initial): commit by wp1, 1st time
$ cat logs/refs/heads/master
0000000000000000000000000000000000000000 1671ae856c149673436da08f1ba026469c3a918d Kevin Fu 1281230735 +0800 commit (initial): commit by wp1, 1st time
$ cat logs/HEAD
0000000000000000000000000000000000000000 1671ae856c149673436da08f1ba026469c3a918d Kevin Fu 1281230735 +0800 commit (initial): commit by wp1, 1st time
$ cat logs/refs/heads/master
0000000000000000000000000000000000000000 1671ae856c149673436da08f1ba026469c3a918d Kevin Fu 1281230735 +0800 commit (initial): commit by wp1, 1st time
可以看到,这两个文件的内容目前是一样的。这个文件记录了什么呢?它记录的是工作目录的状态变化。其中,那一串0表示,一起是从零开始的,因为 git在初始化工作目录时,并没有创建任何对象,要表示初始状态,只好用40个0来表示了。后面那串,就是指向刚才的本次的commit对象。这条记录解释出来,就是:在1281230735 +0800时刻,由Kevin Fu做了一次提交,工作目录从初始状态,转到commit 1671ae8对应的状态。
这个时候,用过git的人可能会生疑问:用git log看到的输出不是这个样子的呀。说对了,git log的输出,并不是由这里的log文件产生的,我认为,它的内容是根据commit之间的关联关系,实时计算并显示出来的。而这里的logs,是git 中的reflog,用git reflog命令可以查看:
Bash代码
$> git reflog
1671ae8 HEAD@{0}: commit (initial): commit by wp1, 1st time
$> git reflog
1671ae8 HEAD@{0}: commit (initial): commit by wp1, 1st time
这个内容,就跟上面的对应上了吧。为什么说这个log文件很重要呢?因为在git中,objects其实都是死的,绝大多数情况下,一旦创建就不会被修改,也不会被删除;当版本控制的
内容发生变化时,只有新的objects被创建出来,没有旧的objects被改变。那么一堆死东西,如何实现灵活的版本变化呢?第一个就是靠不断变化的版本指针,比如HEAD以及refs/heads/master文件,第二个,就是靠记录工作目录变化情况的日志文件。有了日志文件,你想查看谁就查看谁,想往哪个版本跳就往哪个版本跳,想合并谁就合并谁。许多git命令,都是基于这个思想而设计的。
接下来,我再添加一个文件file2.txt,但不是在master branch中,而是新开一个branch: advanced,我们看看开分支的时候,监控有何变化:
Bash代码
$> git checkout -b advanced
(monitor outputs)
Changed file: index