git学习之一:内部对象工作原理

版本控制在于文件的控制,git的控制方法在于为每个文件生成(key,object)的结构。git利用sha-1加密算法,对每一个文件生成一个唯一的字符序列(明文大小不超过2^64位,对于普通文件,这个大小都可以满足)作为hash_key。对于sha-1算法,明文(对于git来讲,就是我们的文件内容)不变,其sha-1值不会改变,所以只要文件改变,就会生成一对新的(key,object)[对于key,当中还有一些细微的处理,不仅仅只是sha-1算法,这里我们只是需要理解,git为一个文件生成了一个唯一的key]。

使用git
init初始化一个本地仓库,打开隐藏目录.git,其内容如下图。可以看到一个objects的目录,里面只有info和pack两个空文件夹。初始化的时候不存在任何object,也就是没有任何文件被记录下来。

1.blob对象

我们在工作目录下添加一个文件file_1.txt,里面只要一个字符串"file1 content",使用git
hash-object [文件名],可以查看其经过算法生成的hash-key.这个一个40个字符长度的序列。其序列为d9039017ab6c958678a334446aadfe5047266027

这个时候object目录下还是空,使用git
add file_1.txt之后,object里会多一个对象,下面详细来解析这个对象。首先看看object目录发生了什么事情

多了一个d9的目录

d9目录下

可以看到40位的hash-key 前两位作为目录名,后38位作为文件名,标识了这个object对象,这个对象里面的内容就是刚才file_1.txt里的内容,可以查看这个对象的内容和对象类型:

git
cat-file -p [hash-key] 可以查看已经存在的object对象内容

git
cat-file -t [hash-key] 可以查看已经存在的object对象类型

git object有四种类型,这是目前我们接触到的第一种类型blob,用来储存文件类容,它的具体内容就是刚刚新建的txt里的字符串file1 content。

2.tree对象

blob对应文件的内容,tree对象可以理解为目录,它的树节点信息包含文件名,hash-key,文件类型、权限等等。这样就可以组织整个需要控制文件的结构

下面我们再往工作目录下添加一个目录dir_1,在dir_1添加一个文件1.txt,类容为"1.txt content"。使用git add 将内容加入到暂存区(也称index,目前不是本文的重点,会在后续章节中详解)。使用git
hash-object来查看生成的key值。

对于文件可以看到生成了hash-key,但是对于目录很明显没有达到预期的效果。我们看看object目录

只存在一个6d的目录,也就是6dc2bcda0c359c6dbb917dec90ca4a8d078ff789对应的1.txt文件,这时我们的目录并没有生成tree对象,tree对象是在commit的过程中生成的,其生成会根据.git目录下的index文件的内容来创建。git
add的操作就是将文件的信息保存到index文件中,在commit时,根据index的内容来生成tree对象。

使用git
ls-files --stage命令,我们看看index里的类容

可以看到index包含了创建tree对象的信息
文件类型(100644),ash-key,目录结构和文件名。

下面我们进行第一次commit,生成commit对象,同时生成tree对象。我们这里具体看看tree对象,master是分支名,master^{tree},表示master分支所指向的tree对象。

可以看到这个tree对象是我们的工作目录,目录下还有一个dir_1的tree对象,和file_1的blob对象,下面看看dir_1对应的tree对象的内容,这个tree对象只包含1.txt的信息。

目前我们的git仓库的内部结构如下:

3.commit对象

介绍tree对象时,提到过commit,只有在commit的时候,才会根据index记录的内容生成tree对象,那么commit对象里只有两个类容:1.代表工作目录的tree对象的key,上一个commit的key。

现在看看我们的object目录:

目前我们的对象数量还不多,每个目录里有一个对象,就是五个对象,刚才的总体tree图,只包含了四个对象,我们使用git
log查看commit的历史

90对应的文件夹里面的文件就是我们的commit对象,它指向工作目录tree,和上一次的commit,这是第一个commit
,所以上一个commit不存在。

对象类型为commit
内容指向工作目录tree,所以能获取到一个commit,就可以完整得到当前的文件状况,现在我们的完整的object图如下:

现在我们在工作加入一个新的目录dir_2,和该目录下文件2.txt,内容为"content 2",在add和commit之后,我们在看看新的commit的信息

新的commit指向了上一个commit,还指向了一个新生成的tree,这个tree表示了新的工作目录情况,看看这tree的类容:

这个tree包含了当前的文件目录和内容,现在我们的对象完整的图如下:

可以看到commit对象指向了工作目录tree,这样只要切换commit,就可以随意切换我们的版本类容。现有有9个object对象了,我们来看看.git/objects目录,对象还很少,没有在出现同一目录下的两个文件的情况。

4.tag对象

git最重要的只有上述三种对象:blob(记录文件内容),tree(目录结构),commit(工作目录tree,提交历史)。对于tag只是一种指向某个commit的对象,它标识了一个commit,并且永久指向它,为该定义一个更加友好的名字而已,这里不作演示。

小结:本文通过讲解git内部的四种对象来解释git的内部工作机制,对于熟悉git使用的人,可以帮助其深入理解。对于版本控制的初学者,只需要了解大概,可以在了解其他章节之后再进一步理解

时间: 2024-08-27 18:44:18

git学习之一:内部对象工作原理的相关文章

aJax学习之Ajax工作原理

转自:http://www.cnblogs.com/mingmingruyuedlut/archive/2011/10/18/2216553.html 在写这篇文章之前,曾经写过一篇关于AJAX技术的随笔,不过涉及到的方面很窄,对AJAX技术的背景.原理.优缺点等各个方面都很少涉及null.这次写这篇文章的背景是因为公司需要对内部程序员做一个培训.项目经理找到了我,并且征询我培训的主题,考虑到之前Javascript.CSS等WEB开发技术都已经讲解过了,所以决定针对AJAX这一块做一个比较系统

spring学习9 Spring工作原理及其作用

1.springmvc请所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责负责对请求进行真正的处理工作. 2.DispatcherServlet查询一个或多个HandlerMapping,找到处理请求的Controller. 3.DispatcherServlet请请求提交到目标Controller 4.Controller进行业务逻辑处理后,会返回一个ModelAndView 5.Dispathcher查询一个或多个ViewResolver视图解析器,找到Mo

从Struts2源码学习Struts2的工作原理

今天我和我好基友啊斌通过探讨struts2的源码,总结了一下它的原理,代码是不会骗人的. 总的来说:struts的工作原理有7步: 1 客户端初始化一个指向Servlet容器的请求: 2 这个请求经过一系列的过滤器 在项目部署的时候,由tomcat容器读取项目的web.xml文件,测试的web.xml文件如下: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5&quo

Git:三、工作原理

首先,我们对工作区也就是文件夹中的文档进行修改. 然后,把修改并需要存档的文档用add命令放到暂存区,并且可以放很多文档. 最后,一个阶段的工作告一段落,使用commit命令把暂存区的内容一股脑存到Git仓库的master(目录分支)里. 原文地址:https://www.cnblogs.com/ZhengWH/p/10370038.html

大数据学习笔记2--hdfs工作原理及源码分析

windows下配置hadoop hadoop 安装包解压,路径不要有特殊字符 lib和bin直接解压出来的不可用,需要自己重新编译 配置环境变量:HADOOP_HOME,path中添加:bin目录 namenode 整个文件系统的管理节点.它维护着整个文件系统的文件目录树,文件/目录的元信息和每个文件对应的数据块列表.接收用户的操作请求. 响应客户端的请求,上传文件: client申请上传文件,namenode查看元数据信息,查看客户端申请的路径是否已存在 namenode返回可用的datan

puppet入门与掌握之puppet工作原理(原理篇)

对于puppet的的掌握,理解puppet的工作原理是一个必要的的阶段,只有在了解了puppet的工作原理后才能更好应用puppet,下面让我们一起了解学习puppet的工作原理: 说到puppet的工作原理,不得不从以下四个方面来说到,如下所示: (1)定义:使用Puppet特定的语言定义基础配置信息.通常我们把这些信息写在Modules中. (2)模板:在配置执行之前检测代码,但并不真正执行. (3)执行:定义的配置自动部署.检测并记录下所发生变化的部分. (4)报告:将期待的变化.实际发生

【git学习一】git的原理

1.背景 git是比较流行的版本管理软件,博主才疏学浅,到目前为止只用过svn和git.虽然git也用了较长时间了,但是还是没有深入学习过,这周打算阅读Progit,对git有一个深入的总结,另外把git的一些主要命令总结下,方便日后学习工作中使用. 2.git简史 读了一遍Progit第一章节,印象比较深刻的有如下几点. 1.git的底层是数据库,这样我们就大体明白git的基本原理,把项目的快照按照编码存入数据库. 2.git的最早是由linux社区的开发者开发的,膜拜大神! 3.git的主要

Git的思想和基本工作原理2

那么,简单地说,Git 究竟是怎样的一个系统呢?请注意,接下来的内容非常重要,若是理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余. 在开始学习 Git 的时候,请不要尝试把各种概念和其他版本控制系统(诸如 Subversion 和 Perforce 等)相比拟,否则容易混淆每个操作的实际意义.Git 在保存和处理各种信息的时候,虽然操作起来的命令形式非常相近,但它与其他版本控制系统的做法颇为不同.理解这些差异将有助于你准确地使用 Git 提供的各种工具. 直接记录快照,而非

Git的思想和基本工作原理

Git的思想和基本工作原理 Chapter: 开始了解Git 1. 先谈谈版本控制的一些事 2. Git诞生背后的一些故事 3. 版本控制:集中式VS分布式 4. Git的思想和基本工作原理 5. Git在Windows下的安装 那么,简单地说,Git 究竟是怎样的一个系统呢?请注意,接下来的内容非常重要,若是理解了 Git 的思想和基本工作原理,用起来就会知其所以然,游刃有余. 在开始学习 Git 的时候,请不要尝试把各种概念和其他版本控制系统(诸如 Subversion 和 Perforce