尽管每天你都会用到Git,常用的命令可能不到5个,但你可能现在还搞不懂它的工作原理。为什么Git可以管理版本?基本命令git add和git commit到底在干什么?
在这篇文章中,我将用一个例子来解释Git的运行过程,帮助你理解Git的工作原理。
1. 初始化
让我们创建一个项目的目录,然后进入该目录。
$ mkdir git-demo-project
$ cd git-demo-project
如果想管理项目的版本,那么我们应该做的第一件事情就是通过git init初始化。
$ git init
git init只做了一件事情,那就是在项目的根目录下创建.git子目录来保存版本信息。
$ ls .git
branches/
config
description
HEAD
hooks/
info/
objects/
refs/
上述命令显示了.git子目录中的内容。
2. 保存对象
接下来让我们创建一个新的空文件test.txt。
$ touch test.txt
然后把这个文件添加到Git代码库中,这一步将创建test.txt现有内容的一个副本。
$ git hash-object -w test.txt
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
在上述代码中,git hash-object命令将test.txt现有的内容压缩成二进制文件,并保存到Git中。该压缩文件叫做Git对象,保存在.git/objects目录中。
我们可以通过这个命令根据对象的文件名获取当前内容,并计算成SHA1 哈希(长度为40的字符串)。让我们看看下列新生成的Git对象文件。
$ ls -R .git/objects
.git/objects/e6:
9de29bb2d1d6434b8b29ae775ad8c2e48c5391
如上述代码所示,.git/objects目录下又多出了一个子目录,而且这个子目录名是上述哈希值的前两个字符。在这个子目录下有一个文件,文件名是上述哈希值中其余的38个字符。
让我们再来看看文件内容。
$ cat .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
上述代码输出的文件内容是一些二进制字符。你可能会问既然test.txt是空文件,又怎么会有这些内容呢?这是因为该二进制对象中还存储了一些元数据。
如果你想看看该文件原始的文本内容,那么应该使用git cat-file。
$ git cat-file -p