git早期版本源码分析2
write-tree
这个程序的功能就是将index
文件的内容读取出来,新建一个tree对象存储进去。
首先猜测index
里面内容的大小。然后对于其中的每一条记录,验证SHA1的合法性,将其中的name和st_mode属性放到同一个buffer里面。最后把这个buffer作为tree对象做压缩求SHA1存到文件夹里面去。
下面是老练的buffer和offset赋值:
1 | offset += sprintf(buffer + offset, "%o %s", ce->st_mode, ce->name); |
这个文件的复杂性主要在于预先分配了一定的空间给buffer,因此会减少一些不断resize的负担。
read-tree
这个程序用于读取一个存储tree对象的文件。主要流程是读取输入的SHA1值的文件验证文件类型,然后输出文件的文件名和状态。
show-diff
这个程序的功能在于查看已经存储的内容跟现在的文件的区别。
首先还是读取index
文件。然后根据每条记录里面的name
属性获取文件的状态然后与index中存储的状态相比较,获得一个按位表示改变的量。然后如果改变了,则去读取存储的SHA1文件。然后使用了一个管道^1将新旧文件内容一起扔给了diff -u
这么一个命令,来在屏幕上显示输出。
cat-file
这个程序用于显示已经存储的文件,可以读取任意一种对象。通过用户给出的SHA1值,读取该文件,然后创建一个临时文件,将读取到的内容存到这个文件里面。
commit-tree
这个程序用于提交tree得到一个commit文件。这里会尝试从环境变量中获取用户信息,如果没有则使用系统存储的用户信息。然后和给定的tree对象的SHA1值以及给定的父提交的SHA1值一起,放到一个文件里面,标明是一个commit对象文件。
接下来
这一段直接翻译自git用户手册
如果你已经掌握了初始提交的想法,你应该查看一个更新的版本,并浏览 cache.h
,object.h
和 commit.h
。
在早期,Git(在 UNIX 的传统中)是一些非常简单的程序,你在脚本中使用它们,将一个输出转换成另一个。这对于最初的开发很有利,因为更容易测试新事物。然而,最近很多部分已经成为内置的,并且其中一些核心已经被 “libified”(即为了性能,便携性的原因而被放入 libgit.a
中,并且避免代码重复)。
到目前为止,您已经知道index
是什么(并在 cache.h 中找到相应的数据结构),而且这只有几个对象类型(blobs,trees,commits和tags)。它们会从struct object
结构体中继承它们的公共结构。这个结构体是他们的第一个成员(这表示,例如您可以使用(struct object *) commit
来实现与&commit -> object
相同的效果,即获取对象名称和标记)。
现在是时候休息一下,并且让这些信息更深入了。