Git 是一套内容寻址文件系统。很不错。不过这是什么意思呢? 这种说法的意思是,Git 从核心上来看不过是简单地存储键值对(key-value)。它允许插入任意类型的内容,并会返回一个键值,通过该键值可以在任何时候再取出该内容。
我们都知道当我们初始化一个仓库的时候,也就是执行以下命令后,文件夹内会生成一个.git文件夹,
git init
内部会包含,以下文件夹。
- hooks //钩子文件夹,内部文件实际上就是一些特定时间触发的shell脚本,我们可以简单的做一个部署系统,每次提交特定tag的时候,则部署最新的代码到服务器。
- objects //真正的内容存放的文件夹,下面重点讲下这里。
- refs //refs目录存放了各个分支(包括各个远端和本地的HEAD)所指向的commit对象的指针(引用),也就是对应的sha-1值;同时还包括stash的最新sha-1值
- config //git配置信息,包括用户名,email,remote repository的地址,本地branch和remote branch的follow关系
- HEAD //存放的是一个具体的路径,也就是refs文件夹下的某个具体分支。意义:指向当前的工作分支。项目中的HEAD 是指向当前 commit 的引用,它具有唯一性,每个仓库中只有一个 HEAD。在每次提交时它都会自动向前移动到最新 的 commit
- index //存放的索引文件,可使用 git ls-files --stage 查看。应该zlib加密后的,PHP可使用gzdeflate()函数
这是objects文件夹,可以看到都是些数字和字符,实际上就是十六进制数。
下图是进入00文件夹后所有文件。
认识下GIT对象: blob对象, tree对象, commit对象
1.创建blob对象
下面我们直接上底层命令, 运行此命令后,会在 .git/objects 文件夹下生成一个 两个字符 的文件夹,文件夹内部文件即类似上图中文件一样。
echo 'test' | git hash-object -w --stdin
git hash-object -w test.txt
分解命令:
hash-object: 计算文本内容的sha-1(哈希值)
-w : 加上此参数后,会把内容写入/objects文件夹,不加则仅仅是计算(不可使用此法单纯做计算用,因为GIT计算的HASH,其基础内容与原内容有所区别)
--stdin : 此参数接收来自于标准输入的内容,即前面的 echo 'test'; 不加此参数,则直接写入某个文本
所以实际上我们看到的,objects 文件夹下的内容,文件名实际上是 hash 值。文件夹是40个字符的前两个(拥有相同前2位的hash值会被分配到同一个文件夹中), 具体文件名则是后面38个字符。使用hash值的原因就在于,位数够多,并且hash值唯一,一点小变化,都会生成新的hash值,和md5算法是一样的道理。
注意:此hash值