.git 目录中有什么?

好吧,我想你们中的大多数人每天都或多或少地使用 git,但是您是否研究过 git 创建的 .git 文件夹中的内容?本文[1]我们将一起探索一下,了解里面到底发生了什么。

git 在基本层面上只是一堆通过文件名相互链接的文本文件。

init

众所周知,我们从 git init 开始我们的 git 之旅。这给出了我们现在可能已经习惯的信息,特别是如果你开始并放弃了很多副项目。

Initialized empty Git repository in /home/meain/dev/src/git-talk/.git/

让我们看看目前 .git 存储库中有什么。

$ tree .git

.git
├── config
├── HEAD
├── hooks
│   └── prepare-commit-msg.msample
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

它似乎创建了一堆文件和文件夹。这些都是什么?让我们一一回顾一下。

  • config 是一个文本文件,其中包含当前存储库的 git 配置。如果你仔细研究它,你会看到你的存储库的一些基本设置,如作者、文件模式等。
  • HEAD 包含存储库的当前头。根据您设置的“默认”分支,它将是 refs/heads/master 或 refs/heads/main 或您设置的任何其他分支。正如您可能已经猜到的,这指向您可以在下面看到的 refs/heads 文件夹,并指向一个名为 master 的文件,该文件目前还不存在。该文件主文件仅在您第一次提交后才会显示。
  • hooks 包含可以在 git 执行任何操作之前/之后运行的任何脚本。
  • objects包含 git 对象,即存储库中有关文件、提交等的数据。
  • refs 存储引用(指针)。 refs/heads 包含指向分支的指针,refs/tags 包含指向标签的。

add

现在您已经了解 .git 中的初始文件集是什么,让我们执行第一个操作,将某些内容添加到 .git 目录中。让我们创建一个文件并添加它(我们还没有提交它)。

echo 'meain.io' > file
git add file

这会执行以下操作:

--- init       2024-07-02 15:14:00.584674816 +0530
+++ add        2023-07-02 15:13:53.869525054 +0530
@@ -3,7 +3,10 @@
 ├── HEAD
 ├── hooks
 │   └── prepare-commit-msg.msample
+├── index
 ├── objects
+│   ├── 4c
+│   │   └── 5b58f323d7b459664b5d3fb9587048bb0296de
 │   ├── info
 │   └── pack
 └── refs

如您所见,这会导致两个主要变化。它修改的第一件事是索引文件。索引存储有关当前暂存内容的信息。这用于表示名为 file 的文件已添加到索引中。

第二个也是更重要的变化是在其中添加了一个新文件夹objects/4c和一个文件5b58f323d7b459664b5d3fb9587048bb0296de。

文件里有什么?

这是我们详细了解 git 如何存储内容的地方。让我们首先看看其中存在哪些类型的数据。

$ file .git/objects/5c/5b58f323d7b459664b5d3fb9587048bb0296de
.git/objects/4c/5b58f323d7b459664b5d3fb9587048bb0296de: zlib compressed data

嗯,但是 zlib 压缩数据是什么?

$ zlib-flate -uncompress <.git/objects/4c/5b58f323d7b459664b5d3fb9587048bb0296de
blob 9\0meain.io

看起来它包含我们执行 git add 的名为 file 的文件的类型、大小和数据。在本例中,数据表明它是一个大小为 9 的 blob,内容是 meain.io。

文件名是什么?

嗯,好问题。它来自于内容的sha1。如果您获取 zlib 压缩数据并通过 sha1sum 进行管道传输,您将获得文件名。

$ zlib-flate -uncompress <.git/objects/4c/5b58f323d7b459664b5d3fb9587048bb0296de|sha1sum
4c5b58f323d7b459664b5d3fb9587048bb0296de

git 获取要写入的内容的 sha1,获取前两个字符(在本例中为 4c),创建一个文件夹,然后使用其余部分作为文件名。 git 从前两个字符创建文件夹,以确保单个对象文件夹下没有太多文件。

向 git cat 文件问好

事实上,由于这是 git 中比较重要的部分之一,因此 git 还有一个管道命令来查看对象的内容。您可以使用 git cat-file,其中 -t 表示类型,-s 表示大小,-p 表示内容。

$ git cat-file -t 4c5b58f323d7b459664b5d3fb9587048bb0296de
blob

$ git cat-file -s 4c5b58f323d7b459664b5d3fb9587048bb0296de
9

$ git cat-file -p 4c5b58f323d7b459664b5d3fb9587048bb0296de
meain.io

commit

现在我们知道添加文件时会发生什么变化,让我们通过提交将其提升到一个新的水平。

$ git commit -m 'Initial commit'
[master (root-commit) 4c201df] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 file

以下是发生的变化:

--- init        2024-07-02 15:14:00.584674816 +0530
+++ commit      2023-07-02 15:33:28.536144046 +0530
@@ -1,11 +1,25 @@
 .git
+├── COMMIT_EDITMSG
 ├── config
 ├── HEAD
 ├── hooks
 │   └── prepare-commit-msg.msample
 ├── index
+├── logs
+│   ├── HEAD
+│   └── refs
+│       └── heads
+│           └── master
 ├── objects
+│   ├── 3c
+│   │   └── 201df6a1c4d4c87177e30e93be1df8bfe2fe19
 │   ├── 4c
 │   │   └── 5b58f323d7b459664b5d3fb9587048bb0296de
+│   ├── 62
+│   │   └── 901ec0eca9faceb8fe0a9870b9b6cde75a9545
 │   ├── info
 │   └── pack
 └── refs
     ├── heads
+    │   └── master
     └── tags

哇,看来有很多变化。让我们一一浏览它们。第一个是新文件 COMMIT_EDITMSG。顾名思义,它包含(最后的)提交消息。

如果您在不带 -m 标志的情况下运行 git commit 命令,那么 git 获取提交消息的方式是使用 COMMIT_EDITMSG 文件打开编辑器,让用户编辑提交消息,一旦用户更新并退出编辑器,git 使用文件的内容作为提交消息。

它还添加了一个全新的文件夹日志。这是 git 记录存储库中所有提交更改的一种方式。您将能够在此处看到所有引用和 HEAD 的提交更改。

对象目录也进行了一些更改,但我希望您首先查看 refs/heads 目录,其中我们现在有文件 master.txt。您可能已经猜到这是对 master 分支的引用。让我们看看里面有什么。

$ cat refs/heads/master
3c201df6a1c4d4c87177e30e93be1df8bfe2fe19

看起来它指向新对象之一。我们知道如何观察物体,让我们这样做吧。

$ git cat-file -t 3c201df6a1c4d4c87177e30e93be1df8bfe2fe19
commit

$ git cat-file -p 3c201df6a1c4d4c87177e30e93be1df8bfe2fe19
tree 62902ec0eca9faceb8fe0a9870b9b6cde75a9545
author Abin Simon <mail@meain.io> 1688292123 +0530
committer Abin Simon <mail@meain.io> 1688292123 +0530

Initial commit

你也可以这样做 git cat-file -t refs/heads/master

嗯,看起来那是一种新的对象。这似乎是一个提交对象。提交对象的内容告诉我们,它包含一个哈希值为 62902ec0eca9faceb8fe0a9870b9b6cde75a9545 的树对象,它看起来像我们提交时添加的另一个对象。提交对象还包含有关作者和提交者是谁的信息,在本例中都是我。最后还显示了此提交的提交消息是什么。

现在让我们看看树对象包含什么。

$ git cat-file -t 62902ec0eca9faceb8fe0a9870b9b6cde75a9545
tree

$ git cat-file -p 62901ec0eca9faceb8fe0a9870b9b6cde75a9545
100644 blob 4c5b58f323d7b459664b5d3fb9587048bb0296de    file

树对象将以其他树和 blob 对象的形式包含工作目录的状态。在本例中,由于我们只有一个名为 file 的文件,因此您只会看到一个对象。如果您看到的话,该文件指向我们执行 git add 文件时添加的原始对象。

这是更成熟的仓库的树的样子。更多的树对象用于从提交对象链接的树对象内部来表示文件夹。

$ git cat-file -p 2e5e84c3ee1f7e4cb3f709ff5ca0ddfc259a8d04
100644 blob 3cf56579491f151d82b384c211cf1971c300fbf8    .dockerignore
100644 blob 02c348c202dd41f90e66cfeb36ebbd928677cff6    .gitattributes
040000 tree ab2ba080c4c3e4f2bc643ae29d5040f85aca2551    .github
100644 blob bdda0724b18c16e69b800e5e887ed2a8a210c936    .gitignore
100644 blob 3a592bc0200af2fd5e3e9d2790038845f3a5cf9b    CHANGELOG.md
100644 blob 71a7a8c5aacbcaccf56740ce16a6c5544783d095    CODE_OF_CONDUCT.md
100644 blob f433b1a53f5b830a205fd2df78e2b34974656c7b    LICENSE
100644 blob 413072d502db332006536e1af3fad0dce570e727    README.md
100644 blob 1dd7ed99019efd6d872d5f6764115a86b5121ae9    SECURITY.md
040000 tree 918756f1a4e5d648ae273801359c440c951555f9    build
040000 tree 219a6e58af53f2e53b14b710a2dd8cbe9fea15f5    design
040000 tree 5810c119dd4d9a1c033c38c12fae781aeffeafc1    docker
040000 tree f09c5708676cdca6562f10e1f36c9cfd7ee45e07    src
040000 tree e6e1595f412599d0627a9e634007fcb2e32b62e5    website

change

让我们对文件进行更改,看看它是如何工作的。

echo 'blog.meain.io' > file
$ git commit -am 'Use blog link'
[master 68ed5aa] Use blog link
 1 file changed, 1 insertion(+), 1 deletion(-)

它的作用如下:

--- commit      2024-07-02 15:33:28.536144046 +0530
+++ update      2023-07-02 15:47:20.841154907 +0530
@@ -17,6 +17,12 @@
 │   │   └── 5b58f323d7b459664b5d3fb9587048bb0296de
 │   ├── 62
 │   │   └── 901ec0eca9faceb8fe0a9870b9b6cde75a9545
+│   ├── 67
+│   │   └── ed5aa2372445cf2249d85573ade1c0cbb312b1
+│   ├── 8a
+│   │   └── b377e2f9acd9eaca12e750a7d3cb345065049e
+│   ├── e5
+│   │   └── ec63cd761e6ab9d11e7dc2c4c2752d682b36e2
 │   ├── info
 │   └── pack
 └── refs

好吧,我们添加了 3 个新对象。其中之一是包含文件新内容的 blob 对象,一个是树对象,最后一个是提交对象。

让我们从 HEAD 或 refs/heads/master 再次追踪它们。

$ git cat-file -p refs/heads/master
tree 9ab377e2f9acd9eaca12e750a7d3cb345065049e
parent 3c201df6a1c4d4c87177e30e93be1df8bfe2fe19
author Abin Simon <mail@meain.io> 1688292975 +0530
committer Abin Simon <mail@meain.io> 1688292975 +0530

Use blog link

$ git cat-file -p 9ab377e2f9acd9eaca12e750a7d3cb345065049e
100644 blob e5ec63cd761e6ab9d11e7dc2c4c2752d682b36e2    file

$ git cat-file -p e6ec63cd761e6ab9d11e7dc2c4c2752d682b36e2
blog.meain.io

那些关注的人可能已经注意到,提交对象现在有一个名为parent的附加键,它链接到先前的提交,因为此提交是在先前的提交之上创建的。

branch

我们是时候创建一个分支了。让我们使用 git branch fix-url 来做到这一点。

--- update      2024-07-02 15:47:20.841154907 +0530
+++ branch      2023-07-02 15:55:25.165204941 +0530
@@ -27,5 +28,6 @@│   └── pack└── refs├── heads
+    │   ├── fix-url│   └── master└── tags

这会在 refs/heads 文件夹下添加一个新文件,其中文件作为分支名称,内容作为最新提交的 id。

$ cat .git/refs/heads/fix-url
68ed5aa2372445cf2249d85573ade1c0cbb312b1

这几乎就是创建分支的全部内容。 git 中的分支确实很便宜。标签的行为方式也相同,只不过它们是在 refs/tags 下创建的。

在logs目录下也添加了一个文件,用于存储类似于master分支的提交历史数据。

检查分支

在 git 中签出是指 git 获取提交的树对象并更新工作树中的文件以匹配其中记录的状态。在这种情况下,由于我们从 master 切换到 fix-url,两者都指向相同的提交和底层树对象,因此 git 在工作树中没有任何事情可做。

git checkout fix-url

当您在 .git 中进行签出时发生的唯一变化是 .git/HEAD 文件现在将指向 fix-url。

$ cat .git/HEAD
ref: refs/heads/fix-url

如果我们在这里,做出commit。我需要这个来展示稍后合并的作用。

echo 'https://blog.meain.io'>file
$ git commit -am 'Fix url'

合并

主要有3种合并方式。

  1. 最简单也是最容易的就是快进合并。在这种情况下,您只需更新一个分支指向另一个分支指向的提交。这几乎涉及将 refs/heads/fix-url 中的哈希复制到 refs/heads/master。
  2. 第二个是变基合并。在这种情况下,我们首先将更改应用到 main 当前一次指向一个提交的内容之上,然后执行类似于快进合并的操作。
  3. 最后一种是使用单独的合并提交来合并两个分支。这有点不同,因为它的提交对象中有两个父条目。我们将在最后进一步讨论这一点。

首先让我们看看合并之前的图表是什么样子的。

git log --graph --oneline --all
* 42c6318 (fix-url) Fix url
* 67ed5aa (HEAD -> master) Use blog link
* 3c201df Initial commit

现在执行合并:

$ git merge fix-url # updates refs/heads/master to the hash in refs/heads/fix-url

$ git log --graph --oneline --all
* 42c6318 (HEAD -> master) (fix-url) Fix url
* 67ed5aa Use blog link
* 3c201df Initial commit

push

现在我们已经使用本地 git 存储库一段时间了,让我们看看推送它时会发生什么。什么正在发送到另一端的 git 存储库?

为了展示这一点,首先让我创建另一个 git 存储库,它可以用作此存储库的远程。

$ mkdir git-talk-2
cd git-talk-2 && git init --bare

cd ../git-talk && git remote add origin ../git-talk-2

现在push

$ git push origin master

让我们看看我们的仓库发生了什么变化。

--- branch 2023-07-02 15:55:25.165204941 +0530
+++ remote 2023-07-02 17:41:05.170923141 +0530
@@ -22,12 +29,18 @@
 │   ├── e5
 │   │   └── ec63cd761e6ab9d11e7dc2c4c2752d682b36e2
 │   ├── info
 │   └── pack
 ├── ORIG_HEAD
 └── refs
     ├── heads
     │   ├── fix-url
     │   └── master
+    ├── remotes
+    │   └── origin
+    │       └── master
     └── tags

它添加了一个新的 refs/remotes 来存储有关不同remote中所有可用内容的信息。

但是什么会被发送到另一个 git 存储库呢?它是对象中和引用下的所有内容。这就是其他 git 实例获取整个 git 历史记录所需的全部内容。

Reference

[1]

Source: https://blog.meain.io/2023/what-is-in-dot-git/

本文由 mdnice 多平台发布

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(H5轮播)vue一个轮播里显示多个内容/一屏展示两个半内容

效果图 : html: <div class"content"><van-swipeclass"my-swipe com-long-swipe-indicator":autoplay"2500"indicator-color"#00C4FF"><van-swipe-itemclass"flex-row-wrap"v-for"(items, index) in M…

React +AntD + From组件重复提交数据(已解决)

开发场景&#xff1a; react Hooks andt 提交form表单内容给数据库(使用antd的form组件) 问题描述 提交是异步的&#xff0c;请提交方式是POST 方式 提交表单内容给后端&#xff0c;却产生了两次提交记录&#xff08;当然&#xff0c;数据新增了两条数据&#xff09;。可以…

VR虚拟展厅的亮点是什么?有哪些应用?

传统展厅主要是以静态陈列的形式来传达内容&#xff0c;而展示形式则有图片、视频等&#xff0c;虽然视频包含内容多&#xff0c;但是总体具有一定的局限性&#xff0c;客户体验感也较差&#xff0c;往往不能深入了解细节。随着VR技术越来越成熟&#xff0c;VR技术的广泛应用&a…

Qemu镜像安全加密测试

文章目录 简介1.已经过时的qemu自带的加密方式介绍1.1.创建secret uuid的xml1.2.产生uuid1.3.给secret赋值1.4.创建一个存储池1.5.在存储池中创建一个镜像1.6.在虚拟机中使用该镜像 2.弃用以上加密方式2.1.原作者Daniel Berrange的观点2.2.Markus Armbruster更深入的操作 3. LU…

在前端html页面中向服务器发送post登录请求

目录 前言 搭建服务器 搭建前端登录页面 获取表单值 使用axios发送post登录请求 前言 一般在html页面中向服务器发送post请求的模块为登录请求&#xff0c;本文将介绍如何向服务器发送post请求 搭建服务器 如何搭建服务器请看JWT认证这篇文章&#xff0c;有详细的解说。…

性能测试jmeter命令行运行+html测试报告解读

windows下打开jmeter的运行窗口&#xff0c;可以看到提示不要用GUI模式进行负载测试&#xff0c;如果要用负载测试&#xff0c;用cli模式&#xff0c;因为GUI模式运行jmeter比较消耗性能。 命令行模式 windows下找到jemeter所在文件夹&#xff0c;打开cmd输入命令。 jmeter -n…

Leetcode 第 365 场周赛题解

Leetcode 第 365 场周赛题解 Leetcode 第 365 场周赛题解题目1&#xff1a;2873. 有序三元组中的最大值 I思路代码复杂度分析 题目2&#xff1a;2874. 有序三元组中的最大值 II思路代码复杂度分析思路2 题目3&#xff1a;2875. 无限数组的最短子数组思路代码复杂度分析 题目4&a…

基于JAVA+SpringBoot+UniApp+Vue的前后端分离的手机移动端图书借阅平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 随着社会信息化的快速…

IPETRONIK数采与第三方软件集成

一 第三方软件 IPETRONIK公司提供IPEmotion用于车辆测试&#xff0c;但在某些特殊领域也有一些专业的软件&#xff0c;例如标定&#xff0c;则需要IPETRONIK数采来进行压力、温度、转速等信号的采集。 IPETRONIK提供了INCA和CANape插件&#xff0c;且这两款软件均可直接识别到…

微信小程序修改van-popup的背景颜色

效果图&#xff1a; van-popup背景颜色渐变 使用深度修改样式不生效&#xff0c;直接在 custom-style里面修改即可&#xff1b; <van-popup position"bottom"custom-style"height:25%;background:linear-gradient(95deg, #F8FCFF -0.03%, #EDF5FF 64.44…

【Qt之布局】QVBoxLayout、QHBoxLayout、QGridLayout、QFormLayout介绍及使用

在Qt中&#xff0c;布局管理器&#xff08;Layout&#xff09;用于管理窗口中的控件的位置和大小&#xff0c;以适应不同大小的窗口。 常用的布局管理器包括QVBoxLayout、QHBoxLayout、QGridLayout和QFormLayout。 先放张布局UI&#xff1a; 1. QVBoxLayout&#xff08;垂直布…

Linux性能优化--性能工具:磁盘I/O

6.0 概述 本章介绍的性能工具能帮助你评估磁盘I/O子系统的使用情况。这些工具可以展示哪些磁盘或分区已被使用&#xff0c;每个磁盘处理了多少I/O,发给这些磁盘的I/O请求要等多久才被处理。 阅读本章后&#xff0c;你将能够&#xff1a; 确定系统内磁盘I/O的总量和类型(读/写…

使用 ClickHouse 深入了解 Apache Parquet (一)

​ 【squids.cn】 全网zui低价RDS&#xff0c;免费的迁移工具DBMotion、数据库备份工具DBTwin、SQL开发工具等 自2013年作为Hadoop的列存储发布以来&#xff0c;Parquet几乎已经成为一种无处不在的文件交换格式&#xff0c;它提供了高效的存储和检索。这种采纳使其成为更近期的…

为网站配置SSL

HTTPS &#xff08;全称&#xff1a;Hyper Text Transfer Protocol over SecureSocket Layer&#xff09;&#xff0c;是以安全为目标的 HTTP 通道&#xff0c;在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。HTTPS 在HTTP 的基础下加入SSL 层&#xff0c;HTTPS…

AWS S3加密

Hello大家好&#xff61; 在本课时我们将讨论S3加密相关的内容。 S3加密相关是认证考试的一个重要的主题考点&#xff0c;您需要了解亚马逊S3的几种不同类型的加密方式。| 首先是静态数据的加密&#xff0c;静态数据加密是指数据存储在亚马逊S3 数据中心的磁盘上时&#xff0…

Maven的详细介绍(maven的全据配置以及idea中maven的配置)

maven的理解 Maven 是一个强大的项目管理和构建自动化工具&#xff0c;它通过抽象的项目对象模型(POM&#xff1a;Project Object Model)和构建生命周期模型(Project Lifecycle)来对项目及其构建过程进行管理(Dependency Management System)&#xff0c;Maven 最大化的消除了构…

爬虫/scrapy基础

如果文章对你有帮助&#xff0c;欢迎关注、点赞、收藏一键三连支持以下哦&#xff01; 想要一起交流学习的小伙伴可以加zkaq222&#xff08;备注CSDN&#xff0c;不备注通不过哦&#xff09;进入学习&#xff0c;共同学习进步 目录 0x01 安装和简介 0x02 文件作用 0x04 保存…

阿里巴巴店铺所有商品数据接口及店铺商品数据分析

获取阿里巴巴店铺所有商品数据的接口是阿里巴巴开放平台提供的接口&#xff0c;通过该接口可以获取店铺所有商品数据。 通过阿里巴巴开放平台接口获取店铺所有商品数据的方法如下&#xff1a; 在开放平台注册成为开发者并创建一个应用&#xff0c;获取到所需的 App Key 和 Ap…

C语言实现用递归方法求 () = ∑ (^2)

完整代码&#xff1a; // 用递归方法求 ??(??) ∑ (??^2) #include<stdio.h>int func(int n){if (n1){return 1;}else{return n*nfunc(n-1);} }int main() {int n;printf("请输入一个整数");scanf("%d",&n);printf("%d",func(…

微信好友消息自动回复,让你轻松应对好友咨询

有许多用微信做业务、做微商的小伙伴&#xff0c;微信有时候消息太多看不过来&#xff0c;漏看消息&#xff0c;或者不知道怎么引导用户&#xff0c;让他们看到你想让他们看到的消息。微信上用户多微信上的信息容易漏掉&#xff0c;怎么能有时效的回复客户呢&#xff1f;此时你…