热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

GitStepbyStep–(4)探索.git目录

前面一篇文章介绍了Git对象模型,接下来我们就进入.git目录看看到底有什么东西,目录中哪些东西又跟Git对象模型相关。结合这个目录,我们将进一步了解Git的工作原理。.git目录下面就开始进

前面一篇文章介绍了Git对象模型,接下来我们就进入".git"目录看看到底有什么东西,目录中哪些东西又跟Git对象模型相关。结合这个目录,我们将进一步了解Git的工作原理。

.git目录

下面就开始进入.git目录了,通过"ls"命令可以看到.git目录中的文件和子目录:

对于这些文件和目录,下面给出了一些基本的描述。在后面后有logs、objects、refs、index和HEAD更详细的介绍

  • (D) hooks:这个目录存放一些shell脚本,可以设置特定的git命令后出发相应的脚本;在搭建gitweb系统或其他git托管系统会经常用到hook script
  • (D) info:包含仓库的一些信息
  • (D) logs:保存所有更新的引用记录(会在后面介绍引用)
  • (D) objects:所有的Git对象都会存放在这个目录中,对象的SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名
  • (D) refs:这个目录一般包括三个子文件夹:heads、remotes和tags,heads中的文件标识了项目中的各个分支指向的当前commit
  • (F) COMMIT_EDITMSG:保存最新的commit message,Git系统不会用到这个文件,只是给用户一个参考
  • (F) config:这个是Git仓库的配置文件
  • (F) description:仓库的描述信息,主要给gitweb等git托管系统使用
  • (F) index:这个文件就是我们前面文章提到的暂存区(stage),是一个二进制文件
  • (F) HEAD:这个文件包含了一个当前分支(branch)的引用,通过这个文件Git可以得到下一次commit的parent
  • (F) ORIG_HEAD:HEAD指针的前一个状态

 

Git引用

Git中的引用是个非常重要的概念,对于理解分支(branch)、HEAD指针以及reflog非常有帮助。

Git系统中的分支名、远程分支名、tag等都是指向某个commit的引用。比如master分支,origin/master远程分支,命名为V1.0.0.0的tag等都是引用,它们通过保存某个commit的SHA1哈希值指向某个commit。

重新认识HEAD

HEAD也是一个引用,一般情况下间接指向你当前所在的分支的最新的commit上。HEAD跟Git中一般的引用不同,它并不包含某个commit的SHA1哈希值,而是包含当前所在的分支,所以HEAD直接指向当前所在的分支,然后间接指向当前所在分支的最新提交。

为了更形象的解释上面的描述,我们首先查看".git/HEAD"的内容:

ref: refs/heads/master

这就表示HEAD是一个指向master分支的引用,然后我们可以根据引用路径打开"refs/heads/master"文件,内容如下:

4ea6c317a67e73b0befcb83c36b915c1481f2efe

根据前面一片文章的介绍,我们通过这个哈希值查看对象的类型和内容,可以看到这个哈希值对应一个commit,并且通过"git log"可以发现这个commit就是master分支上最新的提交。

所以可以看到,所有的内容都是环环相扣的,我们通过HEAD找到一个当前分支,然后通过当前分支的引用找到最新的commit,然后通过commit可以找到整个对象关系模型,看下图:

引用和分支

直到现在我们都没有开始介绍分支(branch),这里也不准备介绍分支,只是想大概展示一下引用和分支的关系。

假设我们现在除了master分支,又创建了一个release-1.0.0.1的分支,再次查看".git/refs/heads/"目录,可以看到除了master文件之外,又多了一个release-1.0.0.1文件,查看给文件的内容也是一个哈希值。

通过"git show-ref --heads"命令就可以产看所有的头,这些都是HEAD的候选值:

根据前面的讲解,这个commit就是就是release-1.0.0.1分支上最新的提交。同样,当我们把当前分支切换到release-1.0.0.1的时候,HEAD文件的内容也会相应的变成:

ref: refs/heads/release-1.0.0.1

  

再看reflog

看过第二篇文章的同学一定还记得我们是怎么根据reflog去得到一个commit哈希值,然后把repo退回到一个指定的状态。

接下了,我们进入".git/logs"文件夹,可以看到这个文件夹也有一个HEAD文件和refs目录,些就是记录reflog的地方。

查看HEAD文件的内容,发现这个文件将会包含所有分支的reflog记录:

0000000000000000000000000000000000000000 601b527296fea232c84b3661abcbff0576b1272c WilberTian  1419759347 +0800    commit (initial): add calc.py into repo
601b527296fea232c84b3661abcbff0576b1272c c2163e267380f71373f29f922e7089abbb741772 WilberTian
1419769538 +0800 commit: add sub function in calc.py
c2163e267380f71373f29f922e7089abbb741772 4ea6c317a67e73b0befcb83c36b915c1481f2efe WilberTian
1419771391 +0800 commit: add app.py, __init__.py and calc.py
4ea6c317a67e73b0befcb83c36b915c1481f2efe 4ea6c317a67e73b0befcb83c36b915c1481f2efe WilberTian
1419822744 +0800 checkout: moving from master to release-1.0.0.1

进入".git/logs/refs"目录,同样会有master和release-1.0.0.1两个文件,两个文件将会保存各自分支的reflog记录

master的内容:

0000000000000000000000000000000000000000 601b527296fea232c84b3661abcbff0576b1272c WilberTian  1419759347 +0800    commit (initial): add calc.py into repo
601b527296fea232c84b3661abcbff0576b1272c c2163e267380f71373f29f922e7089abbb741772 WilberTian
1419769538 +0800 commit: add sub function in calc.py
c2163e267380f71373f29f922e7089abbb741772 4ea6c317a67e73b0befcb83c36b915c1481f2efe WilberTian
1419771391 +0800 commit: add app.py, __init__.py and calc.py

release-1.0.0.1的内容:

0000000000000000000000000000000000000000 4ea6c317a67e73b0befcb83c36b915c1481f2efe WilberTian  1419822744 +0800    branch: Created from master

  

Git索引(index)

前面文章我们也提到过index/stage,就是更新的暂存区,下面就来看看index文件。

index(索引)示一个存放了已排序的路径的二进制文件,并且每个路径都对应一个SHA1哈希值。在Git系统中,可以通过"git ls-files --stage"来显示index文件的内容:

从命令的输出可以看到,所有的记录都对应仓库中的文件(包含全路径)。通过"git cat-file"命令查看app.py对应的哈希值,可以看到这个哈希值就是代表app.py的blob对象。

现在我们更新app.py文件,加上一个"div(16, 4)"的调用并通过"git add"添加到暂存区,这时发现index中app.py对象的哈希值已经变化了。

通过这个例子,我们也可以理解diff操作应该会有怎样的输出了:

  • git diff:比较WorkSpace和stage,add之前有diff输出;add之后没有diff输出
  • git diff HEAD:比较WorkSpace和repo,add之前之后都有diff输出
  • git diff --cached:比较stage和repo,add之前没有diff输出;add之后有diff输出

 

对象的存储

前面提到所有的Git对象都会存放在".git/objects"目录中,对象SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名。

所以,我们前面提到的master上最新的commit对象的哈希值是"4ea6c317a67e73b0befcb83c36b915c1481f2efe",那么这个对象会被存储在".git/objects/4e/a6c317a67e73b0befcb83c36b915c1481f2efe"。进入objects目录后,我们确实找到了这个文件。

在Git系统中有两种对象存储的方式,松散对象存储和打包对象存储。

松散对象(loose object)

松散对象存储就是前面提到的,每一个对象都被写入一个单独文件中,对象SHA1哈希值的前两位是文件夹名称,后38位作为对象文件名。

打包对象(packed object)

对于松散存储,把每个文件的每个版本都作为一个单独的对象,它的效率比较低,而且浪费空间。所以就有了通过打包文件(packfile)的存储方式。

Git使用打包文件(packfile)去节省空间.。在这个格式中,,Git只会保存第二个文件中改变了的部分,然后用一个指针指向相似的那个文件。

一般Git系统会自动完成打包的工作,在已经发生过打包的Git仓库中,".git/objects/pack"目录下会成对出现很多"pack-***.idx"和"pack-***.pack"文件。关于打包就介绍这么多了,暂时还没有去研究两个文件的内容和原理。

 

总结

这篇文章结合了前一篇的Git对象模型,探索了.git文件夹,通过引用,reflog以及索引的介绍,相信会对Git的工作原理有了更多的了解。

通过这两篇文章介绍下来,感觉对谜一样的Git也慢慢的熟悉了起来。

 


推荐阅读
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文整理了Java中org.gwtbootstrap3.client.ui.Icon.addDomHandler()方法的一些代码示例,展示了Icon.ad ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了机器学习手册中关于日期和时区操作的重要性以及其在实际应用中的作用。文章以一个故事为背景,描述了学童们面对老先生的教导时的反应,以及上官如在这个过程中的表现。同时,文章也提到了顾慎为对上官如的恨意以及他们之间的矛盾源于早年的结局。最后,文章强调了日期和时区操作在机器学习中的重要性,并指出了其在实际应用中的作用和意义。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • PyTorch框架中有一个非常重要且好用的包:torchvision,该包主要由3个子包组成,分别是:torchvision.datasets、torchvision.models、torchv ... [详细]
  • 前端Angular的Post导出Excel,内容全部乱码(不是文件名),而Get方式导出没问题 ... [详细]
author-avatar
zhanghuabing
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有