gpt4 book ai didi

git gc --aggressive 与 git repack

转载 作者:行者123 更新时间:2023-12-01 19:05:09 35 4
gpt4 key购买 nike

我正在寻找减小 git 大小的方法存储库。搜索将我带到 git gc --aggressive大多数时候。我还读到这不是首选方法。

为什么?如果我正在运行,我应该注意什么 gc --aggressive ?
git repack -a -d --depth=250 --window=250推荐过 gc --aggressive .为什么?怎么样repack减少存储库的大小?另外,我不太清楚标志 --depth--window .

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

最佳答案

现在没有区别:git gc --aggressive按照 Linus 在 2007 年提出的建议进行操作;见下文。从 2.11 版(2016 年第 4 季度)开始,git 默认深度为 50。大小为 250 的窗口很好,因为它扫描每个对象的更大部分,但深度为 250 很糟糕,因为它使每个链都指向非常深的旧链对象,这会减慢所有 future 的 git 操作,从而略微降低磁盘使用率。

历史背景

Linus 建议使用 git gc --aggressive(请参阅下面的完整邮件列表帖子)只有当你有,用他的话来说,“一个非常糟糕的包”或“非常糟糕的增量”,但是“几乎总是,在其他情况下,这实际上是一件非常糟糕的事情。”结果甚至可能使您的存储库状况比开始时更糟!

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

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

但这假设您已经 removed unwanted gunk从您的存储库历史记录中获取,并且您已遵循在 git filter-branch documentation 中找到的用于缩小存储库的 list 。 .

git-filter-branch can be used to get rid of a subset of files, usually with some combination of --index-filter and --subdirectory-filter. People expect the resulting repository to be smaller than the original, but you need a few more steps to actually make it smaller, because Git tries hard not to lose your objects until you tell it to. First make sure that:

  • You really removed all variants of a filename, if a blob was moved over its lifetime. git log --name-only --follow --all -- filename can help you find renames.

  • You really filtered all refs: use --tag-name-filter cat -- --all when calling git filter-branch.

Then there are two ways to get a smaller repository. A safer way is to clone, that keeps your original intact.

  • Clone it with git clone file:///path/to/repo. The clone will not have the removed objects. See git-clone. (Note that cloning with a plain path just hardlinks everything!)

If you really don’t want to clone it, for whatever reasons, check the following points instead (in this order). This is a very destructive approach, so make a backup or go back to cloning it. You have been warned.

  • Remove the original refs backed up by git-filter-branch: say

    git for-each-ref --format="%(refname)" refs/original/ |
    xargs -n 1 git update-ref -d
  • Expire all reflogs with git reflog expire --expire=now --all.

  • Garbage collect all unreferenced objects with git gc --prune=now (or if your git gc is not new enough to support arguments to --prune, use git repack -ad; git prune instead).



Date: Wed, 5 Dec 2007 22:09:12 -0800 (PST)
From: Linus Torvalds <torvalds at linux-foundation dot org>
To: Daniel Berlin <dberlin at dberlin dot org>
cc: David Miller <davem at davemloft dot net>,
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: <alpine.LFD.0.9999.0712052132450.13796@woody.linux-foundation.org>
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>

On Thu, 6 Dec 2007, Daniel Berlin wrote:

Actually, it turns out that git-gc --aggressive does this dumb thing to pack files sometimes regardless of whether you converted from an SVN repo or not.



绝对。 git --aggressive大多是哑巴。真的只对以下有用
案例“我知道我有一个非常糟糕的包,我想扔掉
我所做的所有糟糕的包装决定。”

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

在其他 SCM 中,delta 链通常是固定的。可能是“前锋”
或“向后”,它可能会随着您使用存储库而有所发展,
但通常它是对单个文件的一系列更改,表示为
一种单一的 SCM 实体。在 CVS 中,显然是 *,v文件,还有很多
其他系统做相当类似的事情。

Git 也做 delta-chains,但它做的更“松散”。那里
不是固定实体。 Deltas 是针对任何随机的其他版本生成的
git 认为是一个很好的 delta 候选者(具有各种公平的
成功的启发式),并且绝对没有硬性分组规则。

这通常是一件非常好的事情。它适用于各种概念
原因(即,git 内部从不需要真正关心整个
修订链——它根本不考虑增量),但是
这也很棒,因为摆脱不灵活的 delta 规则意味着
git merge 两个文件完全没有问题,
例如——根本就没有任意的 *,v “修订文件”具有
一些 stash 的意思。

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

这就是名字很糟糕的地方 --aggressive进来了。虽然
git 通常会尝试重用 delta 信息(因为这是一个好主意,
并且不会浪费 CPU 时间重新查找我们找到的所有好的增量
更早),有时您想说“让我们从头开始,空白
slate,并忽略之前的所有delta信息,并尝试生成
一组新的增量。”

所以 --aggressive不是真的要咄咄逼人,而是要浪费
CPU 时间重新做一个我们之前已经做的决定!

有时这是一件好事。特别是一些导入工具可以
产生非常糟糕的增量。任何使用 git fast-import 的东西,
例如,可能没有太多好的 delta 布局,所以它可能
值得说的是“我想从头开始。”

但几乎总是,在其他情况下,这实际上是一件非常糟糕的事情。
这会浪费 CPU 时间,特别是如果你真的做了一个
早期的 deltaing 做得很好,最终结果不会重用所有
你已经找到的那些好的增量,所以你实际上最终会得到一个
更糟糕的最终结果呢!

我将向 Junio 发送补丁以删除 git gc --aggressive 文档。它可能很有用,但通常只有在您
真正在非常深的层次上了解它在做什么,并且
文档不能帮助你做到这一点。

一般做增量 git gc是正确的方法,而且更好
比做 git gc --aggressive .它将重新使用旧的增量,并且
当那些旧的 deltas 找不到时(做增量 GC 的原因)
首先!)它将创建新的。

另一方面,“长期的初始导入”绝对是正确的
和涉及的历史”是值得花很多钱的地方
是时候找到真正好的增量了。然后,以后的每个用户(如
只要他们不使用 git gc --aggressive撤消它!)将得到
那个一次性事件的优势。所以特别是对于大项目
历史悠久,可能值得做一些额外的工作,告诉三角洲
寻找疯狂的代码。

所以相当于 git gc --aggressive - 但做得正确 - 是
做(过夜)类似的事情
git repack -a -d --depth=250 --window=250

深度的东西只是关于三角链的深度
(让它们在古老的历史中更长——值得花费空间),和
窗口的事情是关于我们想要每个增量的对象窗口有多大
候选人进行扫描。

在这里,您可能想添加 -f标志(即“全部删除
旧三角洲,”因为你现在实际上是在努力确保这个
实际上找到了好的候选人。

然后它将需要永远一天的时间(即“一夜之间”
东西)。但最终的结果是下游的每个人
存储库将获得更好的包,而无需花费任何精力
对它自己。
          Linus

关于git gc --aggressive 与 git repack,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28720151/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com