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.hobject.h commit.h

在早期,Git(在 UNIX 的传统中)是一些非常简单的程序,你在脚本中使用它们,将一个输出转换成另一个。这对于最初的开发很有利,因为更容易测试新事物。然而,最近很多部分已经成为内置的,并且其中一些核心已经被 “libified”(即为了性能,便携性的原因而被放入 libgit.a 中,并且避免代码重复)。

到目前为止,您已经知道index是什么(并在 cache.h 中找到相应的数据结构),而且这只有几个对象类型(blobs,trees,commits和tags)。它们会从struct object结构体中继承它们的公共结构。这个结构体是他们的第一个成员(这表示,例如您可以使用(struct object *) commit来实现与&commit -> object 相同的效果,即获取对象名称和标记)。

现在是时候休息一下,并且让这些信息更深入了。