git 对象压缩及垃圾对象清理

git 对象压缩及垃圾对象清理

这篇文章让我们来看看 git 的对象压缩机制,前面的几篇文章我们提到,在执行 git add 命令会会把文件先通过 zlib 压缩后放入到「暂存区」,我们先看看这个步骤:

我们这个实例中有一个 1.28m 的 index.js 文件:

在这里插入图片描述

初始化一个仓库,然后执行 git add . 命令把文件添加到「暂存区」,在 04-git 中的概念 文章里我们说过这个命令会生成一个「blob 对象」(也就是在一个 .git/objects 文件中生成一个经过 zlib 压缩的文件):

在这里插入图片描述
在这里插入图片描述

从上图可以看到 index.js 文件体积明显减少了很多,能帮我们节省磁盘空间,而通过 git cat-file <hashId> 就可以查看源文件。

我们先执行一下 commit,此时就会生成一个「tree 对象」和一个「commit 对象」,因为这两个文件存储的是索引,所以非常小。

在这里插入图片描述
在这里插入图片描述

如果我们稍微修改 index.js 文件中的几个字符在重新执行 git add . 命令看看会发生什么:

在这里插入图片描述

可以很明显的看到又多一个差不多大小的文件,我们可以设想到如果我们的原始文件很大,或者执行了非常多次的 add、commit 命令,这个 objects 文件将变得非常大:

在这里插入图片描述
在这里插入图片描述

但是我们的「工作目录」才只有一个 1.28m 的文件,同时每次只是修改了几个字符,对比起来 .git 文件是不是太大了(上图只执行了4次的add、commit操作,当文件多了会更明显)。针对这个问题 Git 提供了一个命令: git gc,这个命令可以把 Git 对象进行压缩。

在这里插入图片描述

在经过 dalta 压缩后,GIt 对象(.git/objects文件中的文件)都会被删除,同时在 .git/objects/pack 文件夹中生成相应的压缩文件:

在这里插入图片描述
在这里插入图片描述

可以看到经过压缩后 .git/objects 文件夹体积又变小了,

.pack 文件体积较大,我们可以很明显猜到这就是存储我们文件的地方,而 .idx 文件储存的就是索引,因为 .git/objects 文件夹里的对象都清除了,但是我们还是可以通过执行 git log 或者其他命令获取到对象相关的信息:

在这里插入图片描述

通过 cat-file 命令还是能查看到「commit 对象」、「tree 对象」、「blob 对象」:

在这里插入图片描述

通过这个 .idx 文件我们就能快速到找到 .pack 文件中对应的 commit 或者 blob的内容。

查看压缩文件

我们可以通过 git verify-pack -v <fileName> 命令来查看压缩文件:

在这里插入图片描述

从上图可以看到,.pack 文件保存了之前 add、commit 生成的「commit 对象」、「tree 对象」、「blob 对象」。我们来重点看看标注的地方:

黄色框内的数字就是文件的大小及压缩等信息,红色线就是第一次add的生成的「blob 对象」,蓝色线就是之后3次 add 生成「blob 对象」,后面同时还带上了第一次add的生成的「blob 对象」,说明记录的只是文件的差异,因此在经过压缩后 .git/objects 文件大小会明显降低。

压缩的作用

在传输过程中减少带宽,减少本地磁盘的占用空间。

我们在执行 push 的时候,推送的就是压缩的 pack 文件(减少带宽,较少上传时间),但是我们本地的仓库并没有被压缩:

在这里插入图片描述

我们来看一个更明显的例子,拉取 vue 的代码:

git clone git@github.com:vuejs/vue.git

在这里插入图片描述

可以看到有 62255 个对象,.git 文件大小为 31.51MB。

在这里插入图片描述

从 .git/objects 文件中也可以看到下载的对象都是经过压缩的。 Git 也提供了一个 unpack-objects 命令来帮助我们把对象解压出来。

不过我们不能直接把 .git/objects/pack 文件夹中的 .pack 文件进行解压,需要移动到其他文件夹中:

在这里插入图片描述

在上图中我们把 .pack 文件移动到 .git 目录下:

在这里插入图片描述
之后执行解压缩命令 git unpack-objects < .git\pack-6abcda5b8a6ba30f796c774e6177e10757ff9865.pack :

在这里插入图片描述

可以看到相比起压缩的 .pack 文件,解压出来的对象占用空间更大,如果我们 clone 仓库的时候,对象没有压缩,那么我们将耗费更多的带宽及下载时间。

垃圾对象清理

我们在执行一些 Git 操作的时候,会生成一些「blob 对象」等,这些没有被引用的对象就是垃圾对象。

什么意思呢,比如我们重复修改一个文件,每次修改后都执行 add 命令添加到「暂存区」,之后执行 commit 保存版本,那么在期间生成的一些「blob 对象」没有被引用(只有最后一次 add 生成的「blob 对象」才被引用了),这些就是垃圾对象。前面说了如果这些文件非常大,那么就会导致 .git 文件变得非常大,因此清理垃圾对象非常重要。

我们来看看下面的示例,执行三次 add 命令和一次 commit,那么就会生成 5 个对象:

在这里插入图片描述
在这里插入图片描述

通过 cat-file 命令来看看「commit 对象」到底引用了哪些对象:

在这里插入图片描述

可以看 7a(「tree 对象」)、d8(「blob 对象」)、c8(「commit 对象」)都是存在引用的,8f、37 文件里的就是垃圾对象。

Git 也提供了一些命令来让我们查看未引用的对象:

git fsck --dangling 或者 git prune -n

在这里插入图片描述

清除命令

  • git prune
  • git gc

git gc 在压缩对象的时候也会执行 git prune。

在执行 git gc 进行压缩后,可以看到 .pack 文件里实际只有三个对象,其余两个垃圾对象并没有被记录下来:

在这里插入图片描述

分支

如果我们在分支上进行 add、commit 操作,之后把这个分支删除掉,那么对于我们来说在分支上生成的这些对象都是垃圾,都是需要清除的,但是对于 Git 来说这些却不是垃圾对象,因为它会觉得我们可能会需要执行 checkout 命令把这些对象重新取出来。

比如我们新建一个 newBranch 分支,修改文件并执行 add 、commit,然后切换回 master 分支把这个分支删除掉:

在这里插入图片描述

在这里插入图片描述

可以看到我们执行 git prune -n 并没有提示有任何的垃圾对象,执行 git prune 删除也没反应。

其实通常我们是不需要删除这种对象的,除非我们非常确定这个对象该删除(存在一些秘密信息或者大量无用文件),那么我们可以执行一下命令:

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0  -c gc.pruneExpire=now gc "$@"

地址

文章仓库地址:https://github.com/leopord-lau/easy-git

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

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

相关文章

【数学】完全剩余系与费马小定理

完全剩余系 我们定义 a i ( 1 ≤ i ≤ n ) a_i(1\le i\le n) ai​(1≤i≤n) 为模 m m m 的完全剩余系当且仅当对于 1 ≤ i , j ≤ n 1\le i,j\le n 1≤i,j≤n 且 i ≠ j i\ne j ij&#xff0c;满足 a i ≢ a j ( m o d m ) a_i\not\equiv a_j\pmod m ai​≡aj​(mo…

短视频账号矩阵系统+无人直播系统源码技术开发

短视频账号矩阵系统无人直播系统源码技术开发涉及到多个领域&#xff0c;包括但不限于前端开发、后端开发、数据库设计、网络通信等。 以下是一些基本技术的步骤和注意事项&#xff1a; 1.技术需求分析设计&#xff1a;首先&#xff0c;需要明确开发短视频账号矩阵系统和无人直…

玩转k8s:yaml介绍

一.Yaml文件详解 1.Yaml文件格式 &#xff08;1&#xff09;Kubernetes 支持 YAML 和 JSON 格式管理资源对象 &#xff08;2&#xff09;JSON 格式&#xff1a;主要用于 api 接口之间消息的传递 &#xff08;3&#xff09;YAML 格式&#xff1a;用于配置和管理&#xff0c;…

Springboot+vue的科研工作量管理系统的设计与实现(有报告),Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的科研工作量管理系统的设计与实现&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的科研工作量管理系统的设计与实现…

python_ACM模式《剑指offer刷题》链表1

题目&#xff1a; 面试tips&#xff1a; 询问面试官是否可以改变链表结构 思路&#xff1a; 1. 翻转链表&#xff0c;再遍历链表打印。 2. 想要实现先遍历后输出&#xff0c;即先进后出&#xff0c;因此可借助栈结构。 3. 可用隐式的栈结构&#xff0c;递归来实现。 代码…

从复杂数据到直观洞察:山海鲸助你一臂之力

作为山海鲸可视化的开发者&#xff0c;我们深知在数据可视化领域的挑战与机遇。山海鲸可视化软件正是我们为应对这些挑战而打造的一款强大工具&#xff0c;旨在为用户提供更高效、更直观的数据呈现方式&#xff0c;本文单纯从数据可视化角度带大家了解一下我们这款软件的优势。…

Nginx问题分析

问题再现 分析问题&#xff1a; 就是通过http://182.44.16.68:8077/web-ui/static/js/chunk-libs.82635094.js 地址访问&#xff0c;找不到对应的js文件 首先确认文件在服务器的位置 发现这个目录下确实有这个js文件&#xff0c;那问题就在于http://182.44.16.68:8077/web-ui…

rabbitmq基础-java-4、Direct交换机

1、简介 在Fanout模式中&#xff0c;一条消息&#xff0c;会被所有订阅的队列都消费。但是&#xff0c;在某些场景下&#xff0c;我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。 2、特点 在Direct模型下&#xff1a; 队列与交换机的绑定&#xff0c;…

Linux网络 ---- PXE高效批量网络装机

目录 一、系统装机 1、系统装机方式 2、系统装机的三种引导方式 3、系统安装过程 二、PXE原理和概念 1、PXE概述 2、搭建PXE网络体系所需条件 3、PXE批量部署的优点 4、PXE通常涉及以下几个组件&#xff1a; 5、PXE实现过程详细 三、搭建过程 1、搭建过程服务详解 …

C++ | 函数重载是什么意思?【面试题】C++支持函数重载的原理是什么?详细讲解

函数重载 一个词有多种含义&#xff0c;可以通过上下文来判断该词的真实含义&#xff0c;即该词被重载了。 “同一个函数名&#xff0c;由于参数个数不同、类型结构不同&#xff0c;在c能够同时使用” 函数重载概念及分类 函数重载&#xff1a;是函数的一种特殊情况&#x…

IO多路复用-select(附通信代码)

IO多路复用-select 1. IO多路复用概述 I/O多路复用&#xff08;I/O Multiplexing&#xff09;是一种通过一种机制同时监听多个文件描述符&#xff08;sockets、文件、设备等&#xff09;的技术。它可以使一个进程在等待多个 I/O 操作完成时不会阻塞&#xff0c;从而提高程序的…

Golang 定时任务的几种实现方法

摘要&#xff1a;在 Golang 开发中&#xff0c;定时任务是常见的需求。本文将介绍几种在 Golang 中实现定时任务的方法&#xff0c;包括 time 包的定时器、ticker&#xff0c;以及第三方库 cron&#xff0c;并通过示例代码展示它们的使用方式。 一、time 包的定时器&#xff08…

luceda ipkiss教程 57:画微环调制器

案例分享&#xff1a;画微环调制器 全部代码如下&#xff1a; from si_fab import all as pdk from ipkiss3 import all as i3class DC(i3.PCell):straight_length i3.PositiveNumberProperty(default200)radius i3.PositiveNumberProperty(default50)spacing i3.Positive…

Spring Cloud Gateway 路由配置策略

Spring Cloud Gateway 路由配置策略 Spring Cloud Gateway 是一个基于 Spring Boot 2.x 和 Spring WebFlux 的轻量级网关服务&#xff0c;用于构建微服务架构中的 API 网关。它提供了一种简单、高效、灵活和可扩展的方式来路由请求到后端的微服务。 Spring Cloud Gateway 的核心…

幻兽帕鲁PalWorld服务器搭建详细教程

幻兽帕鲁PalWorld是一款由Pocketpair开发的游戏&#xff0c;融合了多种玩法&#xff0c;其独特的题材和画风吸引了很多玩家。为了更好地进行游戏体验&#xff0c;很多玩家选择自行搭建服务器。本文将详细介绍如何搭建幻兽帕鲁PalWorld服务器。 第一步&#xff1a;购买服务器 根…

Unity | 渡鸦避难所-8 | URP 中利用 Shader 实现角色受击闪白动画

1. 效果预览 当角色受到攻击时&#xff0c;为了增加游戏的视觉效果和反馈&#xff0c;可以添加粒子等动画&#xff0c;也可以使用 Shader 实现受击闪白动画&#xff1a;受到攻击时变为白色&#xff0c;逐渐恢复为正常颜色 本游戏中设定英雄受击时播放粒子效果&#xff0c;怪物…

verilog的模块参数定义

在Verilog中&#xff0c;模块参数定义的定义分为两种&#xff1a;模块声明时定义的参数和模块体内部定义的参数。 模块声明时定义的参数&#xff08;Module Parameter&#xff09;&#xff1a; 模块声明时定义的参数是在模块实例化时提供的常量值。它们是通过模块实例化语句的参…

小程序直播项目搭建

项目功能&#xff1a; 登录实时聊天点赞功能刷礼物取消关注用户卡片直播带货优惠券直播功能 项目启动&#xff1a; 1 小程序项目创建与配置&#xff1a; 第一步 需要登录小程序公众平台的设置页面进行配置&#xff1a; 首先需要是企业注册的才可以个人不能开通直播功能。服务类…

extends 和 implements

以下是 extends 和 implements 在Java代码中的区别和示例&#xff1a; 示例1&#xff1a;使用 extends 实现类继承 // 定义一个父类 Animal public class Animal {public void eat() {System.out.println("动物在吃东西");}public void sleep() {System.out.printl…

java获取一段视频/mp4的时长

引言 在日常开发中&#xff0c;经常会遇到产品经理提出一个需求“上传视频”&#xff0c;而且还得显示出视频的播放时长&#xff0c;我们直接上最简单的代码&#xff0c;必须是最简单&#xff0c;多一句啰嗦都不准点赞。 How to do 1.提前引入包 <!--视频多媒体工具包 包…