本章通过讨论Git的基本架构组成和一些重要概念,来探讨Git的不同之处和原因。

一: 基本概念

1、版本库。

  1】Git版本库只是一个简单的数据库,包含所有用来维护与管理项目的修订版本和历史记录。

  2】Git版本库不但提供版本库中的所有文件的副本,还提供版本库本身的副本。

  3】版本库配置是不随着clone转移的。

  4】Git维护的两个主要结构: 对象库和索引。

  5】版本库数据存放在  .git目录中。

  6】索引是暂时的信息,对版本库来说是私有的。并且可以按需要创建和修改。

2、Git对象类型

  1】对象库是Git版本库实现的心脏。

  2】对象库包含: 原始数据文件、日志消息、作者信息、日期以及其他用来重建项目的任意版本或分支

    信息。

  3】GIt对象库里的对象只有4种: 块(blob)、目录树(tree)、提交(commit)、标签(tag)。

        

3、索引

  1】索引是一个临时的、动态的二进制文件,它描述整个版本库的目录结构。

  2】项目的状态可以用一个提交和一棵目录树表示。

  3】索引使开发的推进与提交的变更之间能够分离开来。

  4】索引在暂存后会保存变更,知道提交。索引可以将一个复杂的版本库状态过渡到,可推测的更好的状态

  5】索引在合并中起到很重要的作用,例如: 允许管理、检查和同时操作同一个文件的多个版本。

  6】文件位置在  .git/index二进制文件中

  

  7】无法直接查看, 文件对应的对象(object中都有)

  

4、可寻址内容名称(对象内容的SHA1散列值)

  1】Git对象库被组织及实现成一个内容寻址的存储系统。(对象库中的每一个对象都有一个唯一名称)

  2】名称是:向对象的内容应用SHA1得到的SHA1散列值。(就是对象的名字和索引)

  3】SHA1、散列码、对象ID都是这个散列值。

 

5、Git追踪内容

  1】Git追踪的不是文件,而是内容。

  2】Git对象库基于其对象内容的散列值,而不是基于用户原始文件布局的文件名和目录名设置。

  3】如果两个文件内容完全一样,对象库里只存一份blob形式的内容副本。

  4】Git使用文件的完整内容作为散列值,所以Git内部数据库有效地存储每个文件的每个版本,而不是差异。

  5】总结:Git用不同散列值的blob区块来记录文件的历史版本,而不是存储一个文件名和一系列差异。

6、路径名与内容

  1】Git需要维护一个文件列表组成版本库的内容,但它不基于文件名。

  2】Git把文件名视为一段区别于文件内容的数据,Git就把索引从传统数据库的数据中分离了出来。

  3】Git与其他类似系统的比较:

  

  4】Git不关系文件名和目录名,而是记录每一个路径名。通过路径名精确的重建文件和目录。

7、打包文件

  1】Git使用更有效的存储机制:打包文件。

  2】创建打包文件: 首先定位内容非常相似的全部文件,然后为其中的一个文件,存储该文件的整个文件。

       之后在计算其他相似文件与该文件之间的差异并且只存储差异。

  3】只更改或添加文件中的一行,Git可能会存储新版本的全部内容,然后记录修改的那一行作为差异,

     并存储在包里。

  4】Git是内容驱动,计算的差异可以是版本库任何地方的两个文件的差异

     (1、同一个版本的两个相似文件。 2、同一个文件的两个版本)

  5】打包文件和对象库中其他对象存储在一起。也用于网络中版本库的高效数据传输。

二: 对象库图示

8、对象库图示。(引用: 也叫指向)

  1】Git对象之间通过协作形成完整的系统。

  2】blob对象是数据结构的"底端"。它被(tree)树对象引用。

  3】树对象引用若干个blob对象,也可以引用其他树对象。

  4】一个提交对象只能引用一个特定的树对象。

  5】一个标签对象只能引用一个提交对象。

  6】分支不是基本的Git对象,但它在命名提交时很重要。

  7】对象在图示中的表示:

     blob对象: 矩形、 树对象: 三角形、 提交对象: 圆形、 标签对象: 平行四边形、 分支: 圆角矩形。

  

  8】新建一个目录添加一个新文件提交。(稍微复杂点的情况)

  

9、扩展知识:查看Git对象(git  cat-file)

  1】git  cat-file  commit  提交ID,查看提交ID对象。

  

  2】git  ls-tree  树对象ID,查看树对象

  

  3】git  cat-file  blob  blob对象ID,查看blob对象。

  

  4】每一个对象都存在: .git/objects/目录中。

        对象ID前两位是对应的文件名。后面是是文件的名字。

       例如: 2】图     blob对象    cfb80a4.......ce139

    

三、Git在工作时的概念。

1、对象、散列和blob

  1】Git 计算一个blob的SHA1的散列值,把散列值的十六进制会作为文件名放进对象库中

  2】160位的散列值几乎不发生碰撞,  160位对应20个字节。 20个字节对应16进制的40个字节。(一个字节8位, 16进制一个字节4位)

  3】16进制的40个字节,前两个数字是目录名。可以提高文件系统效率。(16进制两个字节,可以生成256个空间,均匀分布提高效率)

  4】 git  rev-parse   索引ID前缀    ,通过索引ID前缀,查询完整的散列值

2、文件和树

  1】Git通过 目录树对象追踪文件的路径名。

  2】Git会给每一个添加的文件创建一个对象,但Git并不会马上为树创建一个对象。

  3】索引更新了,索引跟踪文件的路径名和blob对象。

  4】任何时候都可以从当前索引创建一个树对象。

  5】git  write-tree  命令: 可以捕获索引当前信息的快照。

  6】git  ls-files  XXX 命令:  显示索引和工作区的文件的信息。

  

3、SHA1的说明。

  1】特性: 散列函数在数学意义上是一个真正的函数,对于一个给定的输入,会产生相同的输出。

  2】不同的内容产生了相同的散列值,这才叫做碰撞。

  3】Git通过原始提交的散列值,唯一标识整个数据结构在提交时的状态。

4、树层次结构

  1】Git处理复杂的树层次结构: 文件对应  blob对象,子目录对应  树对象。

5、提交

  1】一个提交对象包含。

    丶标识关联文件的树对象名称。

    丶创作新版本的作者的名字和提交时间。(add)

    丶把新版本放到版本库的提交者的名字和提交时间。(commit)

    丶对本次修订原因的说明。(提示消息)

  2】即使是相同的内容,也会因为提交者名字不同或者提交时间不同。而生成的提交对象不同。

  3】git  show  --pretty=fuller  命令,查看给定提交的其他细节。(比 show  多一个提交者和提交日期信息)

6、标签

  1】有两种基本的标签类型。 轻量型和带附注型。

  2】轻量型: 只是提交对象的引用,被版本库视为私有。这些标签不在版本库中创建永久对象。

  3】带附注型:  创建永久对象,包含我们提供的消息。(根据   RFC4880来使用GnuPG密钥进行数字签名)。

  4】默认情况下,Git命令只对带附注的标签起作用。

  5】git  tag  命令可以创建一个带有提交信息、带有附注且未签名的标签。

    

  6】通常情况下,Git通过某些分支来给特定的提交命名标签。

  7】Git通常给包含版本库整个层次结构的树对象的提交对象打标签。

第四章:基本Git概念(重点)的更多相关文章

  1. 【书评:Oracle查询优化改写】第四章

    [书评:Oracle查询优化改写]第四章 BLOG文档结构图 一.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ① check的 ...

  2. [转]Windows Shell 编程 第四章 【来源 http://blog.csdn.net/wangqiulin123456/article/details/7987933】

    第四章 文件的本质 以前,所有文件和目录都有一个确定的属性集:时间,日期,尺寸,以及表示‘只读的’,‘隐藏的,‘存档的’,或‘系统的’状态标志.然而,Windos95(及后来的WindowsNT4.0 ...

  3. (转)iOS Wow体验 - 第四章 - 为应用的上下文环境而设计

    本文是<iOS Wow Factor:Apps and UX Design Techniques for iPhone and iPad>第四章译文精选,其余章节将陆续放出.上一篇:Wow ...

  4. 【黑金原创教程】【TimeQuest】【第四章】内部延迟与其他

    声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/al ...

  5. 【黑金原创教程】【Modelsim】【第四章】激励文本就是仿真环境

      声明:本文为黑金动力社区(http://www.heijin.org)原创教程,如需转载请注明出处,谢谢! 黑金动力社区2013年原创教程连载计划: http://www.cnblogs.com/ ...

  6. 【全面解禁!真正的Expression Blend实战开发技巧】第四章 从最常用ButtonStyle开始 - PathButton

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第四章 从最常用ButtonStyle开始 - PathButton 上一篇我们介绍了TextButton,但为了追求界面的张力, ...

  7. 《Linux内核设计与实现》读书笔记 第四章 进程调度

    第四章进程调度 进程调度程序可看做在可运行太进程之间分配有限的处理器时间资源的内核子系统.调度程序是多任务操作系统的基础.通过调度程序的合理调度,系统资源才能最大限度地发挥作用,多进程才会有并发执行的 ...

  8. 精通Web Analytics 2.0 (6) 第四章:点击流分析的奇妙世界:实际的解决方案

    精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第四章:点击流分析的奇妙世界:实际的解决方案 到开始实际工作的时候了.哦耶! 在本章中,您将了解到一些最重要的网络分析报告,我将 ...

  9. 《Linux内核设计与实现》课本第四章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第四章自学笔记 进程调度 By20135203齐岳 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统.多任务操作系统使多个进程处于堵 ...

  10. 第三章:Git使用入门

    本文主要讲git的使用,其实网上这种教程已经很多了,但是还是要说一下,在这里先把基础的东西跟大家讲一下,然后再附上一个彩蛋,将一些别人不会提到的git技术,不要错过 哦! First: Git概念 1 ...

随机推荐

  1. NSFW.js 前端使用教程

    引用js + 下载模型 先看文档 https://github.com/infinitered/nsfwjs 非常好,一点也看不懂.总之,先引js,不知道去哪里下载js就上jsdelivr搜一搜 按顺 ...

  2. Delphi 移除窗口最大化按钮

    很遗憾,好像没有直接的代码可以操作,可以试试以下代码: var GWL_Result: Integer; begin GWL_Result:= GetWindowLong(Handle,GWL_STY ...

  3. NLog日志 富文本编辑器

    NLog日志 NLog是什么 NLog是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码.NLog是一个简单灵活的.NET日志记录类库.通过使用NLog,我们 ...

  4. Mysql 索引心得

    1. 频繁查询的字段,应该创建索引. 2.更新非常频繁的字段,不应该创建索引. 3.唯一性太差的字段,比如 gender字段,就不应该创建索引. 4.不会出现在where条件之后的字段,不应该创建索引 ...

  5. 使用docker 创建6节点redis 集群 RedisCluster redis集群

    1.RedisCluster 特点(3主节点redis 集群  及6节点集群) 1.无中心节点,客户端与redis 节点直连,不需要中间代理,(有选举机制 master个数需要奇数个) 2.数据可以被 ...

  6. ubuntu 下如何设置环境变量

    一.设置环境变量的三种方法 1.1 临时设置 export PATH=/home/yan/share/usr/local/arm/3.4.1/bin:$PATH 1.2 当前用户的全局设置 打开~/. ...

  7. C++ STL摘记

    一.string类补充 1.函数示例: (1)find和rfind函数,返回的是下标或者string::npos index=ss.find(s1,pos,num) find从pos(包括)开始往右查 ...

  8. zk-复制安装

      Zookeeper系列一:Zookeeper介绍.Zookeeper安装配置.ZK Shell的使用   一.Zookeeper介绍 1. 介绍Zookeeper之前先来介绍一下分布式 1.1 分 ...

  9. make编译工具教程

    make编译工具教程 背景 CC++编译起来目录结构多的情况需要脚本完成搜索编译-> make 第一课 第三课 makefile常用编程语法: 1 pipe管道符号,用;把命令相连接. 这样就 ...

  10. @JsonFormat

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8" 不管是前端传后台,还是后台传前端, ...