Git内部原理(1)
Git本质上是一套内容寻址文件系统,在此之上提供了VCS的用户界面。
Git底层命令(plumbing) vs 高层命令(porcelain)
Git的高层命令包括checkout、branch、remote等总共约30个,这些命令主要交由用户在命令行界面中使用。而除了高层命令之外,Git还提供一些底层命令,这些命令通常不用于命令行界面,而是交由其它工具和自定义脚本使用。
.Git的目录结构
git init 命令会在文件夹中创建一个.git目录,用于存放所有版本管理相关的内容,其目录结构如下:
1 |
$ ls |
在该目录下,Git的核心保存在HEAD文件和 index objects refs目录下。
objects存储所有的数据内容refs存储指向数据的提交对象的指针HEAD文件指向当前分支index包含了暂存区的信息
Git 对象
Git是一套内容寻址文件系统,本质是通过键值寻找Git对象。
内容寻址文件系统: 它允许插入任意类型的内容,并返回一个键值(40位);通过该键值可以在任何时候提取这部分内容。
数据对象
下面来演示如何向git中插入一个Git数据对象,并获取键值。
git第一个底层命令hash-object
1
2 $ echo 'test content' | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4
这样,就为git系统添加了一个对象,其内容为:
1 |
$ find .git/objects -type f |
表示 Git 存储数据内容的方式──为每份内容生成一个文件,取得该内容与头信息的 SHA-1 校验和,创建以该校验和前两个字符为名称的子目录,并以 (校验和) 剩下 38 个字符为文件命名 (保存至子目录下)。
git第二个底层命令cat-file -p 查看对象内容 -t 查看对象类型
通过git cat-file 命令可以查看Git对象,例如:
1 |
$ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a |
树对象
创建一个index,然后将这个index加入一个已有的tree中
大专栏 Git内部原理(1)">commit对象
可以通过调用
commit-tree命令创建一个提交对象,为此需要指定一个树对象的 SHA-1 值,以及该提交的父提交对象
Git 引用
Git下的引用类型,是指向某个SHA-1值的指针。所有的引用对象都保存在.git/refs文件夹下。引用类型帮助我们记住提交的位置。
如何变更Git的引用类型指向的SHA-1
1
2 git update-ref refs/heads/test cac0ca # 将test指向cac0ca提交
以下将介绍几个重要的引用对象
HEAD引用
HEAD文件指向一个引用对象,用于标识当前分支。我们可以通过如下方式读取HEAD
1 |
cat .git/HEAD |
Git提供修改HEAD的命令symbolic-ref
1 |
git symbolic-ref HEAD refs/heads/test |
符号引用对象(symbolic-ref)是特殊的引用对象,它指向一个引用对象,而不是常规的SHA-1值。所以
symbolic-ref命令可以更新包括HEAD在内的所有符号引用对象。
标签引用
Git中除了数据对象、树对象、提交对象,还有 标签对象。标签对象类似于一个提交对象,包括标签创建者、日期、注释以及一个指向提交对象的指针。反过来,我们可以对任意一个对象打标签,而不局限在提交对象。
标签对象存储在.git/refs/tags文件夹下。
远程引用
如果你添加了一个远程版本库并对其执行过推送操作,Git 会记录下最近一次推送操作时每一个分支所对应的值,并保存在 refs/remotes 目录下。
远程分支存储在目录refs/remotes/[origin]下,其中[origin]是远程仓库的别名。
远程引用和分支(位于 refs/heads目录下的引用)之间最主要的区别在于,远程引用是只读的。 虽然可以 git checkout 到某个远程引用,但是 Git 并不会将 HEAD 引用指向该远程引用。因此,你永远不能通过 commit 命令来更新远程引用。 Git 将这些远程引用作为记录远程服务器上各分支最后已知位置状态的书签来管理。
Git 包文件
当我们对一个较大的文件作了微小的修改,并提交之后,git仓库中会生成一个新的数据对象,其内容与现有内容几乎一致,差别只有一小块修改过的内容。
如果 Git 只完整保存其中一个,再保存另一个对象与之前版本的差异内容,岂不更好?
Git 最初向磁盘中存储对象时所使用的格式被称为“松散(loose)”对象格式。 但是,Git 会时不时地将多个这些对象打包成一个称为“包文件(packfile)”的二进制文件,以节省空间和提高效率。 当版本库中有太多的松散对象,或者你手动执行 git gc 命令,或者你向远程服务器执行推送时,Git 都会这样做。
git包文件存储在.git/objects/pack/目录中。
通过调用命令git verify-package可以查看打包内容:
1 |
$ git verify-pack -v .git/objects/pack/pack-978e03944f5c581011e6998cd0e9e30000905586.idx |
Git 打包对象时,会查找命名及大小相近的文件,并保存最新的版本的完整内容和文件不同版本之间的差异内容。
Git内部原理(1)的更多相关文章
- Git详解之九:Git内部原理
Git 内部原理 不管你是从前面的章节直接跳到了本章,还是读完了其余各章一直到这,你都将在本章见识 Git 的内部工作原理和实现方式.我个人发现学习这些内容对于理解 Git 的用处和强大是非常重要的, ...
- git内部原理
Git 内部原理 无论是从之前的章节直接跳到本章,还是读完了其余章节一直到这——你都将在本章见识到 Git 的内部工作原理 和实现方式. 我们发现学习这部分内容对于理解 Git 的用途和强大至关重要. ...
- Git详解之九 Git内部原理
以下内容转载自:http://www.open-open.com/lib/view/open1328070620202.html Git 内部原理 不管你是从前面的章节直接跳到了本章,还是读完了其余各 ...
- git内部原理-第一篇
本人计划写一些关于<git内部原理>的文章 计划每周一篇
- Git 内部原理 - (7)维护与数据恢复 (8) 环境变量 (9)总结
维护与数据恢复 有的时候,你需要对仓库进行清理 - 使它的结构变得更紧凑,或是对导入的仓库进行清理,或是恢复丢失的内容. 这个小节将会介绍这些情况中的一部分. 维护 Git 会不定时地自动运行一个叫做 ...
- Git 内部原理--初探 .git
说到Git大家应该都非常熟悉,几乎每天都会用到它.在日常使用过程中,我们貌似并不需要关注其内部的原理,只需要记住那几个常用的命令,就可以说自己是会Git的人了.可是,事实真的是这样子的吗?今天我们就来 ...
- Git 内部原理 - (1)底层命令和高层命令 (2Git 对象
文章摘选自git官网,这里复制下来表示我已阅读并学习过一次这些内容: 无论是从之前的章节直接跳到本章,还是读完了其余章节一直到这——你都将在本章见识到 Git 的内部工作原理和实现方式. 我们发现学习 ...
- Git内部原理浅析
Git独特之处 Git是一个分布式版本控制系统,首先分布式意味着Git不仅仅在服务端有远程仓库,同时会在本地也保留一个完整的本地仓库(.git/文件夹),这种分布式让Git拥有下面几个特点: 1.直接 ...
- Git内部原理探索
目录 前言 Git分区 .git版本库里的文件/目录是干什么的 Git是如何存储文件信息的 当我们执行git add.git commit时,Git背后做了什么 Git分支的本质是什么 HEAD引用 ...
随机推荐
- 51nod 1393:0和1相等串
1393 0和1相等串 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等. I ...
- Redis主从复制以及主从复制原理
Redis 是一个开源的使用 ANSI C 语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value 数据库,并提供多种语言的 API.从 2010年 3 月 15 日起,Redis 的开 ...
- 最短路问题--Floyd 畅通工程续
畅通工程续 某省自从实行了很多年的畅通工程计划后,终于修建了很多路.不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多.这让行人很 ...
- winform集成cefSharp,与页面进行交互
/// <summary> /// 为了使网页能够与winForm交互 将 com 的可访问性设置为 true /// </summary> [System.Runtime.I ...
- Nginx无法监听虚拟VIP的问题报:99: Cannot assign requested address
99: Cannot assign requested address #本地网卡上没有10.0.0.3这个IPNginx就会报错: [root@lb01 conf]# /application/ng ...
- C++queue的使用
C++队列是一种容器适配器,提供了一种先进先出的数据结构. 队列(queue)模板类定义在<queue>头文件中 基本操作: 定义一个queue变量:queue<Type> q ...
- javaweb04 ServletRequest&ServletResponse
WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个歌规则就是 HTTP协议HTTP协议是超文本传输协议,它是TCP/IP协议集中的一个应用层协议,用于定义WEB浏览器与WEB服 ...
- CodeForces-1100C NN and the Optical Illusion 简单数学
题目链接:https://vjudge.net/problem/CodeForces-1100C 题意: 题目给出外部圆的数目n和内部圆的半径r,要求求出外部圆的半径以满足图片要求. 显然这是一道数学 ...
- POJ 1789:Truck History
Truck History Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 21376 Accepted: 8311 De ...
- MySQL--Centos7下安装5.7.19
https://dev.mysql.com/doc/refman/5.7/en/binary-installation.html https://segmentfault.com/a/11900000 ...