上一节了解了 Git 的一个重要的概念:暂存区。

暂存区是一个介于工作区和版本库的中间状态,当执行commit时,实际上是将暂存区的内容提交大版本库中,而执行add则是将本次变更添加到暂存区。

上一节中也出现了很多新的问题?比如说 HEAD 是什么?它与 master 是什么关系?

Git对象库探秘

  前面我们查看提交日志的时候,出现了提交ID,一个由40位十六进制数字组成的SHA1哈希值,通过查看日志的详细输出,会看看到更多的SHA1哈希值。

  

  可以看出,一个提交当中包含了三个用 SHA1哈希值 标识的Git 对象ID

  1,commit  99447928556fbc66f267bdcdcd8b4a84678cda60  这是本次提交的唯一标识;

  2,tree     2f468676a412dd91435ad6b8c3706eebba13fa9c  这是本次提交所对应的目录树;

  3,parent   1f2cc329be37c7678bac8c2d1f696effffe61c08     这是本次提交的父提交(上一次提交,第一个提交是没有parent的)

  

  可以使用 git cat-file 命令来彻底研究Git 对象ID,分别查看一下上面的三个对象ID的类型

  

  注意:在引用对象ID的时候,没有必要把整个40位的ID写全,只要保证从头开始的前几位不冲突就行,一般在日常工作中输入前6位即可。

  

  再使用 git cat-file 命令来查看一下对象内容

  

  查看目录树(tree对象)中看到了一个新类型的对象:blob 对象(二进制大对象),这个 blob 对象就保存着 index.html 文件的内容。我们继续使用 git cat-file 命令来查看该 blob对象。

  

  

  那么这些对象都存放在什么地方呢?当然是Git版本库中(.git目录)的 objects 目录下了,对象ID的前2位作为目录,后38位最为文件名。

  

  

  下面的图片展示了Git对象库中各个对象之间的关系

  

  通过 Commit 对象之间的相互关联,可以很容易地识别出一条跟踪链条,这条跟踪链条可以在运行 git log 命令时候通过 --graph选项查看。--pretty=raw参数用于显示每个提交对象的parent属性

  

  最后一个提交没有parent属性,所以跟踪链到此为止,这实际上就是提交的起点。

  

  

  

  OK,我们再来看看 HEAD 和 master 。

  命令 git branch 是分支管理的主要命令,也可以显示当前所在分支

  

  在 master 分支名称前面的星号(*)表明这个分支是当前工作分支,至于什么是分支,后面会有一节专门介绍分支。

  现在连续执行下面的三个命令会看到相同的输出:

  1,git log HEAD

  2,git log master

  3,git log refs/heads/master

  

  这个结果说明了什么呢?

  结果表明,在当前的Git版本库中,HEAD , master 和 refs/heads/master 具有相同的指向!!!现在就到Git版本库(.git目录)中看看究竟。

  首先,在 .git 目录下找到名字为 HEAD 或者 master 的文件,并查看一下 .git/HEAD 文件的内容:

  

  

  .git/HEAD文件的内容翻译过来就是:”指向一个引用:refs/heads/master“。这个就是文件 .git/refs/heads/master了,ok,再看一下.git/refs/heads/master文件的内容:

  

  又是一个SHA1哈希值,那么用 git cat-file 命令来查看它:

  

  这个内容是不是很面熟!原来 master 分支指向的是一个最新的提交ID

  这就是Git分支的实现原理:从任何一个提交开始建立一条历史跟踪链条,用一个文件指向这个链条的最新提交,该文件就可以追踪整个提交历史了,这个文件就是 .git/refs/heads/master

  下面的图标显示了一个完整的真实的版本库结构:

  

  目录 .git/refs 是保存引用的命名空间,其中 .git/refs/heads 目录下的引用又称为分支。

  对于分支,即可以使用正规的长格式的表示打:refs/heads/master ,也可以去掉前面的两级目录用 master 来表明。

最新文章

  1. java22
  2. cssSlidy.js 响应式手机图片轮播
  3. Ubuntu下安装Python3.4
  4. Spring使用jdbcJdbcTemplate和三种方法配置数据源
  5. 【Struts 1】Struts1的基本原理和简介
  6. 基于Bootstrap的超酷jQuery开关按钮插件
  7. LeetCode12 Integer to Roman
  8. linux 文件属性
  9. Debian下VIM的安装和配置
  10. Python3中文件处理
  11. 项目实战2.2—nginx 反向代理负载均衡、动静分离和缓存的实现
  12. CTF线下攻防赛
  13. 腾讯广告联盟 Android SDK(广点通)demo的使用方式
  14. leetcode8:字符串转整数 (atoi)
  15. 【原创】MIPS相关
  16. Centos环境自写脚本查看使用php或nginx占用内存
  17. NC 6系初始化EJB
  18. PHP字符串反转
  19. 拓扑排序 Topological Sort
  20. 31、LinkedHashSet简介和练习

热门文章

  1. C#判断是否相等
  2. DirectX的替代品 SDL 简介
  3. Delphi使用TObject类对象创建接受window消息(使用Classes.AllocateHWnd为对象创建一个尺寸为0的窗口,从而有了Handle)good
  4. 逆向工程mybatis-geneator.xml
  5. 通过内核对象在服务程序和桌面程序之间通信的小问题 good
  6. APP导航设计九法
  7. 用shell做简单的分布式计算
  8. java统计文本中单词出现的个数
  9. 最全java多线程学习总结1--线程基础
  10. Spring Cloud全链路追踪实现(Sleuth+Zipkin+RabbitMQ+ES+Kibana)