浅谈 git 底层工作原理

news2024/11/14 16:24:46

浅谈 git 底层工作原理

系统复习到这里也快差不多了,大概就剩下两三个 sections,这里学习一下 git 的 hashing 和对象。

当然,跳过问题也不大。

config 文件

这里还是会用 redux 的项目,先看一下基本信息:

➜  redux git:(master) cd .git
➜  .git git:(master) ls
COMMIT_EDITMSG config         index          objects
HEAD           description    info           packed-refs
ORIG_HEAD      hooks          logs           refs
➜  .git git:(master) cat config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
[remote "origin"]
        url = https://github.com/reduxjs/redux.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master

config 文件保存的就是所有的本地文件,如更新了本地的用户名,config 也会有对应的更新:

➜  .git git:(master) cat config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
        ignorecase = true
        precomposeunicode = true
[remote "origin"]
        url = https://github.com/reduxjs/redux.git
        fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
        remote = origin
        merge = refs/heads/master
[user]
        name = GA

下面提一个简单的例子,默认的 git branch 看起来是这个样子的:

在这里插入图片描述

通过简单的配置:

[color]
	ui = true
[color "branch"]
	local = cyan
	current = yellow bold

可以将 UI 改成下面这个样子:

在这里插入图片描述

具体的设定很多,可以看下 reference,如果真的感兴趣的话……有些配置真的可以搞得很风骚,但我确实是用的不太多……

ref

refs 下面有三个文件夹:

  • heads

    保存所有的 head,每个文件都以分支的名称结尾,每个文件里面只包含最后一个 commit 的 hash 值:

    cd heads
    ❯ ls
    master     new-branch
    ❯ cat master
    49d04ce8e7ec22917d09eb50f61fe464f324b65f
    
  • remotes

    如文件夹名称所示,这里会下载所有的 remotes,每一个 remote 是一个单独的文件夹,每个文件夹下面包含下载的远程分支。

    cd remotes
    ❯ ls
    origin
    ❯ cd origin
    ❯ ls
    HEAD
    ❯ cat HEAD
    ref: refs/remotes/origin/master
    

    这也是为什么 git 知道分支已经不同了,正巧今天 redux 又做了一个 commit,可以做一个 demo:

    git checkout master
    Switched to branch 'master'
    Your branch is ahead of 'origin/master' by 2 commits.
    (use "git push" to publish your local commits)git fetch
    remote: Enumerating objects: 17, done.
    remote: Counting objects: 100% (17/17), done.
    remote: Compressing objects: 100% (17/17), done.
    remote: Total 17 (delta 9), reused 0 (delta 0), pack-reused 0
    Unpacking objects: 100% (17/17), 15.73 KiB | 644.00 KiB/s, done.
    From https://github.com/reduxjs/redux
    662f1ed1..1d0e692e  master     -> origin/master
    ❯ git status
    On branch master
    Your branch and 'origin/master' have diverged,
    and have 2 and 3 different commits each, respectively.
    (use "git pull" to merge the remote branch into yours)
    
    nothing to commit, working tree clean
    ❯ cat .git/refs/remotes/origin/master
    1d0e692e5e9c6c030523791b107ca536ca2823fd
    
    ❯ git log --oneline
    49d04ce8 (HEAD -> master, new-branch) add new message
    11d94c7a add text to readme
    662f1ed1 Merge pull request #4532 from jimhigson/patch-1
    34308acd (tag: v5.0.0-alpha.6) Merge pull request #4531 from MahendraBishnoi29/patch-5
    378c9276 Fix missing call to `getDefaultMiddleware`
    9944978b update React Fragment link
    8782a6e8 update tutorial link HTML & CSS url (#4528)
    

    在拉取了远程的代码后,远程获得了一个新的 commit hash,这个在本地上是没有的,通过对比后,git 能够获得这样的信息:

    在这里插入图片描述

    通过对比 hash value,git 可以准确的判断,在 662f1ed1 之后,远程和我本地分别有了不同的 commits,而这就造成了不同的分支,因此它提出了 diverged branch 这个说法。

  • tags

    tags 和 refs 相似。

    里面除了保留远程的 tags 之外,还会保留本地的 tags。

    cd tags
    ❯ ls
    diff-tag       v5.0.0-alpha.6
    ❯ cat diff-tag
    30635355a0f4fb6783420273f8d09c0893d52424
    

HEAD

HEAD 是一个文件追踪目前的 HEAD 指向什么地方,一般是一个 branch,或是一个 commit。

二者的区别在 Git 时间线管理 有提到过。

cat .git/HEAD
ref: refs/heads/master
❯ git checkout new-branch
Switched to branch 'new-branch'cat .git/HEAD
ref: refs/heads/new-branch
❯ git checkout b05e4325
Note: switching to 'b05e4325'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at b05e4325 Release 5.0.0-alpha.5
❯ cat .git/HEAD
b05e43256ec2bed86e1180be978b41313cf6529d

objects

objects 包含了所有 git 的备份文件、commits 等,这些文件通常都是压缩且加密(目前 git 用的是 SHA-1 进行加密)的,加密过后的 40 位的值可以用来获取当时这个 commit 文件,文件包含内容如下:

ls .git/objects
11   1b   23   30   45   63   78   96   b5   b9   df   f4   pack
17   1d   26   31   49   67   7d   a3   b7   dc   ee   info
❯ ls .git/objects/11
d94c7a0fb7ef4fdcefb6e701674c2449804abd
❯ ls .git/objects/pack
pack-6e1431c4d78908ed9d91bfa34c7d22b1da735487.idx  pack-6e1431c4d78908ed9d91bfa34c7d22b1da735487.pack
❯ ls .git/objects/info

其加密的语法位 git hash-object <file>,git 将输入的文件加密,并返回 hashed value 作为 key,这样之后可以回溯这时传过去的文件。

# 仅仅是将其输出到 console,用 -w flag 会将这个 command 会写到 objects 里echo 'hello' | git hash-object --stdin
ce013625030ba8dba906f756967f9e9ca394464a
❯ ls .git/objects
11   1b   23   30   45   63   78   96   b5   b9   df   f4   pack
17   1d   26   31   49   67   7d   a3   b7   dc   ee   info
# 下面的记录会写到 objects 中echo 'hello' | git hash-object --stdin -w
ce013625030ba8dba906f756967f9e9ca394464a
❯ ls .git/objects
11   1b   23   30   45   63   78   96   b5   b9   dc   ee   info
17   1d   26   31   49   67   7d   a3   b7   ce   df   f4   pack
❯ ls .git/objects/ce
013625030ba8dba906f756967f9e9ca394464a

git 获取了 2 位字符用作文件夹的名称,随后存储了后 38 位作为单独文件的名称,这样通过 文件夹+文件 的方式,git 就能够获取 40 位 16 进制的值作为 key,去回溯当时提交的文件内容。

想要追溯加密的文件可以用 git cat-file <object-hash>,如:

# -p 代表 pretty printgit cat-file -p ce013625030ba8dba906f756967f9e9ca394464a
hello
# redux 成员做的 commitgit cat-file -p b951537de944539df9e9526be0429234dc2b7aad
tree 67bdbc53959986be15daf89bc98534f4cdaa5fa1
parent 8782a6e8321cb97ce0e21f77874b360593f4363c
author browny <mahendrabrowny@gmail.com> 1682414114 +0530
committer GitHub <noreply@github.com> 1682414114 +0530
gpgsig -----BEGIN PGP SIGNATURE-----

 wsBcBAABCAAQBQJkR5oiCRBK7hj4Ov3rIwAANKgIACwdeWIZ6u8W3YOBLNupe8jr
 B/q/feV5W41G+3+0iCx+JcWtbdCl0H79OCvj0Xm/decgbbf0IO5RYdQ0lOuIXvQu
 kXlNREGTIdlkh7gv2WoRRNjBWL6fQ5LybbmooOcJwCB4f47MMsj5HKnRsKl0XWYW
 C8qn2eQbs09QST4vv4baldTFPVzW4ajL+KHCwXZG76Ou7OFbPzIR7RGg6QPPK0av
 3P30HMeXSlDyxaHLkb6OHIEAyK+Yl+nDvLwdORFeu8wTpe2B0MNiZBqugzerBmwf
 En8ZOht33YKRGwuXbW42qSI2Hi0BJNgUpCnDFaEDyUl2ezicQxhTQPKhWBXrEVw=
 =qYQZ
 -----END PGP SIGNATURE-----


update thunk link%

为了表示 git 会将当前文件 hash 进去,这里继续举个例子:

echo "new file \n love it" > new.txt
❯ cat new.txt
new file
 love it
❯ git hash-object new.txt
dcad5c179ec08ab9dbc57a9dc4be586fb3caaf15
❯ git hash-object new.txt -w
dcad5c179ec08ab9dbc57a9dc4be586fb3caaf15
❯ ls .git/objects/
11   1b   23   30   45   63   78   96   b5   b9   dc   ee   info
17   1d   26   31   49   67   7d   a3   b7   ce   df   f4   pack
❯ ls .git/objects/dc
2c05886aa4658763804b3c295c3e3cadea3414 ad5c179ec08ab9dbc57a9dc4be586fb3caaf15
❯ git cat-file dcad5c179ec08ab9dbc57a9dc4be586fb3caaf15 -p
new file
 love it

这也是为什么在之后的 commit 中删除文件,checkout 到之前的 commit 还是可以追溯回当时的版本的原因。

blob

使用命令行保存的二进制文件就是 blog,blob 中不包含文件名,只保存所有的内容。

每一个 blob 也会有自己的 hash value。

tree

tree 解决了文件名的问题——blob 是不保存文件名的,同时它可以存储多个文件——每个 blob 只保存单独文件的内容。git 中所有的文件都会被保存成 blob 或者 tree,tree 可以对标成文件夹,blob 对标为单独的一个文件。

假设保存的文件结构如下:

|- index.html
|- main.js
|- styles
|  |- main.css
|  |- index.css

对应的储存的 blog 结构如下:

index.html
main.js
styles
main.css
index.css
tree
blob
blob
tree
blob
blob

每个 tree 都会保存对应 blob 和 tree 的引用,除此之外还会保存 mode、type 和文件名,如:

modetypehashed valuefilename
100644blobe03d902a8d2a53c889cc129bda1b0ce2cf718a67.babelrc.cjs

查看当前 tree 的指令为 git cat-file -p <branch | commit hash>^{tree},如:

git cat-file -p master^{tree}
100644 blob e03d902a8d2a53c889cc129bda1b0ce2cf718a67	.babelrc.cjs
040000 tree a2f9306f466054b9d6bac7fec0a5ea8b4eb13637	.codesandbox
100644 blob ed5699bd11a460bab0476e42d9d879ffd7d0580b	.editorconfig
100644 blob efac9cb61b3e7b4501710a9c70ddf81c7e41d7bb	.eslintignore
100644 blob 8f8944f970ee5c1ae83432ec7a1822a56d43cc4d	.eslintrc.cjs
100644 blob 72cfe1819b98b78c1cb600bcbf46702673077b34	.git-blame-ignore-revs
100644 blob cc4ea460c9dc256ad6d38bd605006239d23b1541	.gitbook.yaml

commit

commit 的结构稍微复杂一些,它会包含更多的信息:tree(当前 repo 下的所有内容),parent,author,committer,message,如上面查看过的:

git cat-file -p b951537de944539df9e9526be0429234dc2b7aad
tree 67bdbc53959986be15daf89bc98534f4cdaa5fa1
parent 8782a6e8321cb97ce0e21f77874b360593f4363c
author browny <mahendrabrowny@gmail.com> 1682414114 +0530
committer GitHub <noreply@github.com> 1682414114 +0530
gpgsig -----BEGIN PGP SIGNATURE-----

 wsBcBAABCAAQBQJkR5oiCRBK7hj4Ov3rIwAANKgIACwdeWIZ6u8W3YOBLNupe8jr
 B/q/feV5W41G+3+0iCx+JcWtbdCl0H79OCvj0Xm/decgbbf0IO5RYdQ0lOuIXvQu
 kXlNREGTIdlkh7gv2WoRRNjBWL6fQ5LybbmooOcJwCB4f47MMsj5HKnRsKl0XWYW
 C8qn2eQbs09QST4vv4baldTFPVzW4ajL+KHCwXZG76Ou7OFbPzIR7RGg6QPPK0av
 3P30HMeXSlDyxaHLkb6OHIEAyK+Yl+nDvLwdORFeu8wTpe2B0MNiZBqugzerBmwf
 En8ZOht33YKRGwuXbW42qSI2Hi0BJNgUpCnDFaEDyUl2ezicQxhTQPKhWBXrEVw=
 =qYQZ
 -----END PGP SIGNATURE-----


update thunk link%

其中 gpgsig 以下的部分是实际的 commit message,PGP SIGNATURE 是一个 e-verify 加密,redux 除了 git 之外应该还有其他的验证。

reference

  • git-config - Get and set repository or global options

  • Github merkle DAG

  • How is git commit sha1 formed

  • How is the Git hash calculated?

  • Git Internals - Git Objects

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/467249.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

短视频矩阵系统---开发技术源码能力

短视频矩阵系统开发涉及到多个领域的技术&#xff0c;包括视频编解码技术、大数据处理技术、音视频传输技术、电子商务及支付技术等。因此&#xff0c;短视频矩阵系统开发人员需要具备扎实的计算机基础知识、出色的编程能力、熟练掌握多种开发工具和框架&#xff0c;并掌握音视…

制冷暖通工业互联网平台孵化

制冷暖通工业互联网平台孵化可以帮助初创企业或者创新项目快速建立和推广制冷暖通工业互联网平台。以下是一些常见的制冷暖通工业互联网平台孵化服务&#xff1a; 创业辅导&#xff1a;孵化器提供创业辅导服务&#xff0c;帮助企业或者项目找到合适的市场和商业模式&#xff0c…

sd卡中病毒的表现及sd文件消失后的恢复方法

sd卡在日常使用中十分常见&#xff0c;但有时也会发生一些意外情况。例如&#xff0c;不小心意外感染病毒&#xff0c;导致sd卡中存储的文件消失。那么对于丢失的文件&#xff0c;我们该如何恢复呢&#xff1f;下面将带您了解sd卡中病毒的表现以及sd卡文件消失怎么恢复的方法。…

【C语言】学习路线大纲思维导图

思维导图下载地址&#xff1a;点击跳转   配套专栏&#xff1a;【C语言】基础语法 思维导图 1. 基础语法1.1 变量和数据类型1.2 运算符和表达式1.3 控制流程结构1.4 函数和递归1.5 数组和指针1.6 字符串和字符处理1.7 文件操作 2. 高级特性标准库和常用函数动态内存分配多文件…

理解龙格库塔法基本C程序

先学习龙格-库塔法&#xff1b; 龙格-库塔&#xff0c;Runge-Kutta&#xff0c;该方法用于数值求解微分方程&#xff1b; 其中包括著名的欧拉法&#xff1b; 经典四阶法 该方法主要是在已知方程导数和初值信息&#xff0c;利用计算机仿真时应用&#xff0c;省去求解微分方…

【LeetCode】213. 打家劫舍 II

213. 打家劫舍 II&#xff08;中等&#xff09; 思路 这道题是 198.打家劫舍 的拓展版&#xff0c;区别在于&#xff1a;本题的房间是环形排列&#xff0c;而198.题中的房间是单排排列。 将房间环形排列&#xff0c;意味着第一间房间和最后一间房间不能同时盗窃&#xff0c;因…

虹科分享|不再受支持的Windows系统如何免受攻击?| 自动移动目标防御

传统的微软操作系统(OS)可能会一直伴随着我们&#xff0c;操作系统使用统计数据显示&#xff0c;传统操作系统的总市场份额仍在10%以上。Windows的总安装基数为13亿&#xff0c;大约有1.5亿个终端仍在运行旧版操作系统。 数十万组织的终端和服务器采用不受支持的操作系统。如果…

curl方式调用电商API接口示例 详细介绍

cURL是一个利用URL语法在命令行下工作的文件传输工具&#xff0c;1997年首次发行。它支持文件上传和下载&#xff0c;所以是综合传输工具&#xff0c;但按传统&#xff0c;习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。 cURL支持的通信协议有FTP、FTPS、HTTP、H…

数字化工厂:虹科Vuzix AR眼镜在工业制造中的革新应用

随着现代科学技术和新兴需求的快速增长&#xff0c;增强现实(AR)、各种“现实”产品与技术不断涌入创新市场&#xff0c;新兴用例数量正在快速增长&#xff0c;可以肯定&#xff0c;在可预见的未来&#xff0c;AR技术将成为各行各业的生产与工作主流。 增强现实&#xff08;AR&…

应用scrapy爬虫框架

Scrapy是一个基于Python的开源网络爬虫框架&#xff0c;它可以帮助我们快速、高效地抓取网页数据&#xff0c;并支持数据的自动化处理、存储和导出。Scrapy提供了丰富的扩展机制&#xff0c;可以轻松地实现各种自定义需求。 Scrapy的基本使用流程&#xff1a; 1、安装Scrapy框…

服务(第十五篇)HAproxy负载+高可用

HAProxy负载均衡的调度算法&#xff08;策略&#xff09;&#xff1a; &#xff08;1&#xff09;roundrobin&#xff0c;表示简单的轮询 &#xff08;2&#xff09;static-rr&#xff0c;表示根据权重 &#xff08;3&#xff09;leastconn&#xff0c;表示最少连接者先处理 &…

RestTemplate使用不当引发的504及连接池耗尽问题分析

背景 系统&#xff1a; SpringBoot开发的Web应用&#xff1b;ORM: JPA(Hibernate)接口功能简述&#xff1a; 根据实体类ID到数据库中查询实体信息&#xff0c;然后使用RestTemplate调用外部系统接口获取数据。 问题现象 浏览器页面有时报504 GateWay Timeout错误&#xff0c…

C语言函数大全-- r 开头的函数

C语言函数大全 本篇介绍C语言函数大全-- r 开头的函数 1. raise 1.1 函数说明 函数声明函数功能int raise(int sig);用于向当前进程发送指定的信号。 参数&#xff1a; sig &#xff1a; 指定要发送的信号编号 返回值&#xff1a; 如果调用成功&#xff0c;raise() 函数将返…

霍兰德人格分析雷达图

雷达图 Radar Chart 雷达图是多特性直观展示的重要方式 问题分析 霍兰德认为&#xff1a;人格兴趣与职业之间应有一种内在的对应关系 人格分类&#xff1a;研究型、艺术型、社会型、企业型、传统型、现实性 职业&#xff1a;工程师、实验员、艺术家、推销员、记事员、社会工…

【AUTOSAR】【信息安全】SecOC

目录 一、概述 二、约束和假设 三、依赖模块 四、功能描述 4.1 安全解决方案的规范 4.1.1 安全解决方案的基本实体 4.1.2 安全的I-PDU构建 4.1.3 安全的I-PDU验证 4.2 与PduR的关系 4.3 初始化 4.4 传出PDU的身份验证 4.5 传入pdu的验证 4.6 网关功能 4.7 多核分…

【java】Java中的锁

文章目录 前言一、悲观锁二、乐观锁三、自旋锁原理自旋锁优缺点优点缺点 自旋锁时间阈值(1.6 引入了适应性自旋锁)自旋锁的开启 四、可重入锁(递归锁)五、读写锁六、公平锁七、非公平锁八、共享锁九、独占锁十、轻量级锁十一、重量级锁十二、偏向锁十三、分段锁十四、互斥锁十五…

Docker实战笔记5-利用 commit 理解镜像构成

转载请标明出处&#xff1a;http://blog.csdn.net/zhaoyanjun6/article/details/130338433 本文出自【赵彦军的博客】 文章目录 慎用 docker commit 注意&#xff1a; docker commit 命令除了学习之外&#xff0c;还有一些特殊的应用场合&#xff0c;比如被入侵后保存现场等。但…

【软件测试】测试用例的设计

文章目录 一. 针对没有需求的案例来设计测试用例二. 针对有需求的案例来设计测试用例1. 穷举法2. 等价类3. 边界值4. 判定表法5. 场景设计法5.1 简介5.2 基本设计步骤5.3 基本流和备选流5.4 使用场景5.5 优缺点5.6 实例 6. 错误猜测法 一. 针对没有需求的案例来设计测试用例 针…

网络安全入行?来了解下网络安全从业人员类别及其工作任务

又到了每年重保期间&#xff0c;红蓝双方都开始进行准备蓄势待发&#xff0c;网络安全从业人员每年供不应求&#xff0c;尤其是重保期间&#xff0c;双方都在疯狂的招揽准备网络安全人员。那网络安全从业人员分类到底有哪些&#xff0c;都负责哪些具体的工作任务呢&#xff1f;…

基于云计算技术的B/S架构云HIS 云HIS 云HIS系统

传统的HIS经历了20多年的建设&#xff0c;已经从单机版发展到局域网的版本&#xff0c;更被深入应用到医院的各项业务活动&#xff0c;成为医院必不可缺的基础设施平台&#xff0c;724小时不间断地支撑医院运行。因此医院都十分重视信息化建设。随着医改的不断推进和医疗行业的…