Git 中的对象模型和文件的详细视图
本文将用几幅图来可视化一个叫
file1
的文件从修改到暂存,再到提交的整个过程。相信会对你理解 Git 有一些帮助。
初始状态
初始状态如下图所示:
可以看到,工作目录包含file1
和file2
两个文件,分别包含内容 “foo” 和 “bar”.
除了工作目录下的file1
和file2
之外,master 分支上有一个提交(初始提交),用圆形表示。它指向的三角形其实是一棵树(你可以把它想象成目录),树指向了和file1
和file2
内容完全一样的 “foo” 和 “bar”.
索引中的那个三角形,和对象库的那棵树是完全一样的,它们都指向相同的对象(“foo” 和 “bar”)。
这幅图还告诉我们,分支就是一个指针,指向某个提交。
目前来看,工作区、索引、对象库是完全一致的,没有什么是脏的。
编辑一个文件之后
如图所示,当把文件file1
的内容从 “foo” 改成 “quux” 之后,索引和对象库并没有变化,但是工作目录脏了,因为它和索引不一致了。
暂存文件后
当执行命令git add file1
后,一些有趣的变化发生了。
Git 首先取出工作目录中file1
的最新版本(“quux”),为它的内容计算出一个 SHA1 散列 ID(bd71363),然后把这个 ID 保存在对象库中(当然,文件内容也会保存在对象库中)。接下来,Git 会改变索引,让索引指向新的file1
。由于文件file2
没有变化,所以索引依然指向原来的file2
。
此时,工作目录与索引是一致的。但是,索引和对象库不一致。
提交之后
啊呀,提交之后好像图示有点乱啊。别着急,我来解释一下。
首先,索引对象转化成了一个真实的树对象(深色的三角形),这个对象会以 SHA1 命名(图上没有标出来而已),被放到对象库中。
其次,用你的日志消息创建了一个新的提交对象(深色的圆形)。新的提交对象会指向新创建的树对象,并且指向前一个提交。
最后,master 分支的引用从最近一次提交移动到新创建的提交。
此时,工作目录、索引和对象库再次同步,又变得一致了。
参考资料
《Git 版本控制管理(第2版)》,人民邮电出版社