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

gitgc--aggressivevsgitrepack

如何解决《gitgc--aggressivevsgitrepack》经验,为你挑选了4个好方法。

我正在寻找减少git存储库大小的方法.搜索引导我到git gc --aggressive大多数时间.我还读到这不是首选方法.

为什么?如果我跑步,我应该注意什么gc --aggressive

git repack -a -d --depth=250 --window=250推荐结束gc --aggressive.为什么?如何repack减少存储库的大小?此外,我不太清楚旗帜--depth--window.

我应该怎么选择gcrepack?什么时候应该使用gcrepack



1> Greg Bacon..:

如今没有区别:git gc --aggressive根据Linus 2007年提出的建议运作; 见下文.从版本2.11(2016年第4季度)开始,git默认深度为50.大小为250的窗口是好的,因为它扫描每个对象的较大部分,但是250的深度是坏的,因为它使每个链都指向非常深的旧对象,这会减慢所有未来的git操作,从而降低磁盘使用率.


历史背景

Linus建议(参见下面的完整邮件列表帖子),git gc --aggressive只有当你用他的话说,"一个非常糟糕的包"或"非常糟糕的三角洲",然而"几乎总是,在其他情况下,它实际上是一个非常糟糕的要做的事情."结果甚至可能使您的存储库处于比您开始时更糟糕的状态!

他建议在导入"漫长而复杂的历史"之后正确地执行此操作的命令是

git repack -a -d -f --depth=250 --window=250

但是这假设您已经从存储库历史记录中删除了不需要的gunk,并且您已经按照清单来缩小git filter-branch文档中找到的存储库.

git的过滤分支可以用来摆脱文件的一个子集,通常用的一些组合--index-filter--subdirectory-filter.人们期望生成的存储库小于原始存储库,但是你需要更多的步骤来实际使它变小,因为Git努力不会丢失你的对象,直到你告诉它.首先要确保:

如果blob在其生命周期内被移动,那么您确实删除了文件名的所有变体.git log --name-only --follow --all -- filename可以帮助您找到重命名.

你真的过滤了所有的参考:--tag-name-filter cat -- --all在通话时使用git filter-branch.

然后有两种方法可以获得更小的存储库.更安全的方法是克隆,保持原始原封不动.

克隆它git clone file:///path/to/repo.克隆将没有删除的对象.见git-clone.(请注意,使用普通路径克隆只是硬连接所有内容!)

如果你真的不想克隆它,无论出于何种原因,请检查以下几点(按此顺序).这是一种非常具有破坏性的方法,因此请进行备份或返回克隆它.你被警告了.

删除git-filter-branch备份的原始引用:比如说

git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n 1 git update-ref -d

使用的所有reflog到期git reflog expire --expire=now --all.

垃圾收集所有未引用的对象git gc --prune=now(或者如果你git gc的新参数不足以支持参数--prune,请git repack -ad; git prune改为使用).


Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST)
From: Linus Torvalds 
To: Daniel Berlin 
cc: David Miller ,
    ismail at pardus dot org dot tr,
    gcc at gcc dot gnu dot org,
    git at vger dot kernel dot org
Subject: Re: Git and GCC
In-Reply-To: <4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>
Message-ID: 
References: <4aca3dc20712051947t5fbbb383ua1727c652eb25d7e@mail.gmail.com>
            <20071205.202047.58135920.davem@davemloft.net>
            <4aca3dc20712052032n521c344cla07a5df1f2c26cb8@mail.gmail.com>
            <20071205.204848.227521641.davem@davemloft.net>
            <4aca3dc20712052111o730f6fb6h7a329ee811a70f28@mail.gmail.com>

2007年12月6日星期四,丹尼尔柏林写道:

实际上,事实证明,git-gc --aggressive无论你是否从SVN回购转换,有时打包文件都是愚蠢的事情.

绝对.git --aggressive大多是愚蠢的.它真的只对"我知道我有一个非常糟糕的包装,并且我想抛弃我所做的所有糟糕包装决定"的情况有用.

为了解释这一点,值得解释一下(你可能已经意识到了这一点,但我还是要了解基础知识)git delta-chains如何工作,以及它们如何与大多数其他系统如此不同.

在其他SCM中,delta链通常是固定的.它可能是"前进"或"后退",并且在您使用存储库时它可能会有所改进,但通常它是对单个文件的一系列更改,表示为某种单个SCM实体.在CVS中,它显然是*,v文件,很多其他系统都做类似的事情.

Git也做delta链,但它更"松散"地做了它们.没有固定的实体.Delt是针对git认为是一个优秀的delta候选者的任何随机其他版本生成的(具有各种相当成功的启发式算法),并且绝对没有硬分组规则.

这通常是一件非常好的事情.它有各种概念上的好处(也就是说,git内部从来都不需要关心整个修订链 - 它根本没有根据增量来考虑),但它也很棒,因为摆脱不灵活的delta规则意味着例如,git没有任何问题将两个文件合并在一起 - 根本就没有任意*,v隐藏含义的"修订文件".

这也意味着增加选择是一个更开放的问题.如果你将delta链限制为一个文件,你真的没有很多关于如何处理增量的选择,但在git中,它确实是一个完全不同的问题.

这就是真正命名--aggressive的地方.虽然git通常会尝试重新使用delta信息(因为它是一个好主意,并且它不会浪费CPU时间重新找到我们之前发现的所有好的增量),有时你我想说"让我们从头开始,用空白的石板,忽略所有以前的增量信息,并尝试生成一组新的增量."

所以--aggressive不是真正的积极进取,而是浪费CPU时间重新做出我们之前做过的决定!

有时这是件好事.特别是一些导入工具可能会产生非常糟糕的增量.git fast-import例如,任何使用的东西都可能没有太大的三角洲布局,因此值得说"我想从一个干净的平板开始".

但几乎总是,在其他情况下,这实际上是一件非常糟糕的事情.它会浪费CPU时间,特别是如果你之前在deltaing中做得很好,最终的结果是不会重复使用你已经找到的那些好的增量,所以你实际上最终会得到很多更糟糕的最终结果!

我将向Junio发送补丁以删除git gc --aggressive 文档.它可能很有用,但它通常只有在你真正理解它正在做的事情时才有用,并且文档对你没有帮助.

一般来说,做增量git gc是正确的方法,而不是做git gc --aggressive.它将重新使用旧的增量,当无法找到那些旧的增量时​​(首先进行增量GC的原因!)它将创建新的增量.

另一方面,"长期参与历史的最初导入"绝对是一个值得花费大量时间寻找真正好的增量的点.然后,每个用户之后(只要他们不用git gc --aggressive来撤消它!)将获得该一次性事件的优势.因此,特别是对于历史悠久的大型项目,可能值得做一些额外的工作,告诉delta发现代码疯狂.

因此,相当于git gc --aggressive- 但做得恰当 - 是(过夜)类似的事情

git repack -a -d --depth=250 --window=250

那个深度的东西只是关于三角链的深度(让旧历史更长一些 - 它值得空间开销),窗口的事情是我们希望每个delta候选者扫描多大的对象窗口.

在这里,您可能想要添加-f标志(这是"放弃所有旧的增量",因为您现在实际上正在尝试确保这个实际上找到了好的候选者.

然后它将需要永远和一天( "一夜之间"的事情).但最终的结果是,该存储库下游的所有人都将获得更好的包,而不必自己花费任何精力.

          Linus


您对深度的评论有点令人困惑。刚开始我会抱怨你错了,因为积极进取可以大大加快git存储库的速度。在进行了积极的垃圾收集之后,一个巨大的仓库花了五分钟的时间才变成git状态,减少到几秒钟。但是后来我意识到您并不是说侵略性的gc减慢了回购速度,而是很大的深度。

2> VonC..:

我什么时候应该使用gc&repack?

正如我在" Git垃圾收集似乎没有完全发挥作用 "中提到的那样,a git gc --aggressive本身就不够,甚至不够.

最有效的组合是添加git repack,但也git prune:

git gc
git repack -Ad      # kills in-pack garbage
git prune           # kills loose garbage

注意:Git 2.11(2016年第4季度)会将默认gc激进深度设置为50

请参阅Jeff King()提交07e7dbf(2016年8月11日).(由Junio C Hamano合并- -提交0952ca8,2016年9月21日)gc aggressive
peff

gitster:默认积极深度为50

" gc"用于将delta-chain长度限制为250,这对于获得额外的空间节省而言太深,并且对运行时性能不利.
限制已降至50.

总结是:当前默认值250不会节省太多空间,并且会花费CPU.这不是一个很好的权衡.

" git gc --aggressive"标志--aggressive做三件事:

    使用" git-gc"抛弃现有的增量并从头开始重新计算

    使用"--window = 250"来增加增量效果

    使用"--depth = 250"来制作更长的三角链

项目(1)和(2)是"积极"重新包装的良好匹配.
他们要求重新包装做更多的计算工作,以期获得更好的包装.您在重新包装期间支付成本,而其他操作仅看到好处.

第(3)项不太清楚.
允许更长的链意味着对增量的限制更少,这意味着可能找到更好的链并节省一些空间.
但这也意味着访问增量的操作必须遵循更长的链,这会影响它们的性能.
所以这是一个权衡,并且不清楚这种权衡甚至是一个好的权衡.

(参见研究承诺)

您可以看到,随着我们减小深度,常规操作的CPU节省会得到改善.
但我们也可以看到,随着深度的增加,节省的空间并不是那么大.在10到50之间节省5-10%可能值得CPU权衡.节省1%从50到100,或另外0.5%从100到250可能不是.


说到CPU保存," -f"学会接受该git repack选项并将其传递给pack-objects.

请参阅Junio C Hamano()提交的40bcf31(2017年4月26日).(由Junio C Hamano合并- -2017年5月29日的提交31fb6f4中)--threads=
gitster

重新包装:接受gitster并传递给--threads=

我们已经对这样做的pack-objects--window=; 当用户想要强制--depth=进行可重复的测试而不受赛车多线程的影响时,这将有所帮助.


我在"Git Garbage集合似乎没有完全发挥作用"链接中提到了Linus线程

3> Sascha Wolf..:

问题git gc --aggressive是选项名称和文档具有误导性.

正如Linus本人在这封邮件中解释的那样,git gc --aggressive基本上是这样的:

虽然git通常会尝试重新使用delta信息(因为它是一个好主意,并且它不会浪费CPU时间重新找到我们之前发现的所有好的增量),有时你想说"让我们从头开始,用一个空白石板,并忽略所有以前的增量信息,并尝试生成一组新的增量".

通常不需要在git中重新计算增量,因为git确定这些增量非常灵活.只有你知道你有非常非常糟糕的增量才有意义.正如Linus所解释的那样,主要使用的工具git fast-import属于这一类.

大多数时候git在确定有用的增量方面表现相当不错,并且使用git gc --aggressive会留下增量,这可能会在浪费大量CPU时间的情况下更糟糕.


莱纳斯结束了他的邮件与结论,即git repack用大--depth--window在大多数时间是更好的选择; 特别是在你导入一个大项目并想确保git找到好的增量之后.

因此,相当于git gc --aggressive- 但做得恰当 - 是(过夜)类似的事情

git repack -a -d --depth=250 --window=250

那个深度的东西只是关于三角链的深度(让旧历史更长一些 - 它值得空间开销),窗口的事情是我们希望每个delta候选者扫描多大的对象窗口.

在这里,你可能想要添加-f标志(这是"丢弃所有旧的增量",因为你现在实际上是在努力确保这个实际上找到了好的候选者.



4> Sage Pointer..:

警告.git gc --agressive如果没有备份,请不要使用与远程同步的存储库运行.

此操作从头开始重新创建增量,如果正常中断,可能会导致数据丢失.

对于我的8GB计算机,攻击性gc在1Gb存储库上运行内存不足10k次.当OOM杀手终止git进程时 - 它给我留下了几乎空的存储库,只有工作树和少数三角洲幸存下来.

当然,它不是存储库的唯一副本,所以我只是重新创建它并从远程拉出(fetch不能用于破坏的回购并且在'解决增量'步骤上遇到了很多次我试图这样做),但如果你的回购是没有遥控器的单开发商本地仓库 - 首先备份它.


推荐阅读
  • 修正我的GitHub commit 数据
    早晨上班,滴滴搭车里,我在掘金这个帖子看到大家晒自己的Github活跃记录,我也晒了下自己的记录。不过太少了。有遗漏的commits状况这也让我知道,自己觉得自己很忙的,实际上提交 ... [详细]
  • Git GitHub多人协作
    在学校做一个小项目需要多人协作,就用到了gitHub,百度了一下多数写得乱七八糟或者支离破碎,于是总结了一下自己的步骤如下,第一次使用GitHUb,哪里不对望大神指出一.前期准备: ... [详细]
  • 阿里Treebased Deep Match(TDM) 学习笔记及技术发展回顾
    本文介绍了阿里Treebased Deep Match(TDM)的学习笔记,同时回顾了工业界技术发展的几代演进。从基于统计的启发式规则方法到基于内积模型的向量检索方法,再到引入复杂深度学习模型的下一代匹配技术。文章详细解释了基于统计的启发式规则方法和基于内积模型的向量检索方法的原理和应用,并介绍了TDM的背景和优势。最后,文章提到了向量距离和基于向量聚类的索引结构对于加速匹配效率的作用。本文对于理解TDM的学习过程和了解匹配技术的发展具有重要意义。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Explain如何助力SQL语句的优化及其分析方法
    本文介绍了Explain如何助力SQL语句的优化以及分析方法。Explain是一个数据库SQL语句的模拟器,通过对SQL语句的模拟返回一个性能分析表,从而帮助工程师了解程序运行缓慢的原因。文章还介绍了Explain运行方法以及如何分析Explain表格中各个字段的含义。MySQL 5.5开始支持Explain功能,但仅限于select语句,而MySQL 5.7逐渐支持对update、delete和insert语句的模拟和分析。 ... [详细]
  • 三、查看Linux版本查看系统版本信息的命令:lsb_release-a[root@localhost~]#lsb_release-aLSBVersion::co ... [详细]
  • 一、设置时区方法一:使用setup工具setup选择Timezoneconfiguration选择AsiaShanghai空格键勾选上System ... [详细]
  • golang源码分析调度概述
    golang源码分析-调度过程概述本文主要概述一下golang的调度器的大概工作的流程,众所周知golang是基于用户态的协程的调度来完成多任务的执行。在Linux ... [详细]
  • Word2vec,Fasttext,Glove,Elmo,Bert,Flairpre-trainWordEmbedding源码数据Github网址:词向量预训练实现Githubf ... [详细]
  • 开发笔记:Squid代理服务
    本文由编程笔记#小编为大家整理,主要介绍了Squid代理服务相关的知识,希望对你有一定的参考价值。Squid服务基础缓存代理概述 ... [详细]
author-avatar
云沏-茶
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有