如何管理大型git代码库?

8

我有一个非常大(超过1 GB)的git代码仓库,每当我们在新的本地实例上设置这个仓库时,总会出现问题。是否有任何已证明的方法来解决这个问题?


5
可以从代码库中删除导致其膨胀到1GB的大型二进制文件(可以在SO上查找如何操作)。如果您确实没有此类文件,而所有1GB都是源代码,则您必须拥有一个非常庞大的代码库。 - Tim Biegeleisen
使用Subversion进行部分克隆(而不是git)怎么样? - iBug
可能是如何处理大型Git存储库?的重复问题。 - Rumid
3个回答

8
如果您不需要完整的历史记录,并且正在使用相当新的Git版本(1.9或更高版本),则可以进行浅层克隆:
  • git clone --depth 5 user@host:repo.git将截断每个分支上最近的5个提交并缩减repo历史记录。
  • git clone --shallow-since=2017-12-01 user@host:repo.git将截断自2017年12月1日以来的所有repo历史记录。
  • git clone --shallow-exclude=abc1234 user@host:repo.git将克隆除指定修订版及其可达修订版以外的每个修订版。您可以多次使用--shallow-exclude以指定多个不想要的修订版。
您还可以像这样克隆单个分支:git clone --branch master --single-branch user@host:repo.git,这将仅拉取指定repo上master分支的历史记录。 在https://www.atlassian.com/blog/git/handle-big-repositories-git有更多详细信息,可能会很有帮助 - 尤其是如果您正在处理具有大型二进制资源的repo。

3

在共享文件系统上设置一个“depot”克隆存储库,其中包含旧历史记录,且其中的内容不会更改。所有进一步的克隆都应使用--reference引用该存储库,并且其内容不会复制到新克隆体中。请阅读克隆文档以了解如何使用此功能,例如在失去(或可能失去)对参考存储库的访问权限之前应该做什么。


请您详细说明如何设置“depot”克隆存储库? - prajwal_stha
最简单的方法是将其克隆到广泛共享的文件系统位置,永远不要再次推送、拉取或获取,仅用作参考。您可以选择删除对更近期代码的引用,以便所有引用它的克隆体都能在自己的对象数据库中获得最新内容,而不是从共享仓库中读取,如果访问共享文件系统很慢,那将会有所不同。 - jthill

1

现在有 microsoft/scalar(它三年前作为GVFS开始,然后是VFS for Git,它移动到了自己的代码库
现在,从2019年8月起,Scalar

Scalar: 一套用于Git的工具和扩展,允许非常大的monorepos在Git上运行而不需要虚拟化层。

如果您的存储库托管在支持GVFS协议的服务上,例如Azure Repos,那么scalar clone <url>将创建一个本地注册,具有按需对象检索、后台维护任务和自动设置Git配置值和钩子以实现性能增强的功能。
Scalar还可以帮助设置稀疏注册。
它与Git for Windows 2.38(2022年10月)集成。
它在Git 2.35(2022年第一季度)中有文档记录:

scalar:开始记录该命令

由Johannes Schindelin签署

Scalar是一个有主见的代码库管理工具。 通过使用Scalar创建新的代码库或将现有代码库注册到Scalar中,您的Git体验将会加速。 Scalar设置了高级的Git配置设置,后台维护您的代码库,并帮助减少网络传输的数据量。
Scalar的一个重要概念是"enlistment":这是项目的顶层目录。 通常包含子目录"src/",它是一个Git工作树。这鼓励跟踪文件(在"src/"内)和未跟踪文件(如构建产物,在"src/"外)之间的分离。
当将名称不为"src"的现有Git工作树注册到Scalar时,enlistment将与工作树相同。
"scalar"命令实现了各种子命令,并根据子命令提供不同的选项。
再次强调:它与Git for Windows 2.38(2022年10月)集成。

在Git 2.27(2020年第二季度)中,"git fetch"对scalar clone提供了更好的支持。

它还解释了scalar clone与普通git clone的区别,并且可以处理更大的代码库。

请参阅commit b739d97(2020年3月13日),作者为Derrick Stolee(derrickstolee
(由Junio C Hamano -- gitster --commit 4cd9bb4合并,2020年3月25日)

connected.c:为特殊情况重新准备打包 帮助者:Jeff King 帮助者:Junio Hamano 签署者:Derrick Stolee

While updating the microsoft/git fork on top of v2.26.0-rc0 and consuming that build into Scalar, I noticed a corner case bug around partial clone.

The "scalar clone" command can create a Git repository with the proper config for using partial clone with the "blob:none" filter.
Instead of calling "git clone", it runs "git init" then sets a few more config values before running "git fetch".

In our builds on v2.26.0-rc0, we noticed that our "git fetch" command was failing with

error: https://github.com/microsoft/scalar did not send all necessary objects

This does not happen if you copy the config file from a repository created by "git clone --filter=blob:none <url>", but it does happen when adding the config option "core.logAllRefUpdates = true".

By debugging, I was able to see that the loop inside check_connnected() that checks if all refs are contained in promisor packs actually did not have any packfiles in the packed_git list.

I'm not sure what corner-case issues caused this config option to prevent the reprepare_packed_git() from being called at the proper spot during the fetch operation. This approach requires a situation where we use the remote helper process, which makes it difficult to test.

It is possible to place a reprepare_packed_git() call in the fetch code closer to where we receive a pack, but that leaves an opening for a later change to re-introduce this problem.
Further, a concurrent repack operation could replace the pack-file list we already loaded into memory, causing this issue in an even harder to reproduce scenario.

It is really the responsibility of anyone looping through the list of pack-files for a certain object to fall back to reprepare_packed_git() on a fail-to-find. The loop in check_connected() does not have this fallback, leading to this bug.

We _could_ try looping through the packs and only reprepare the packs after a miss, but that change is more involved and has little value.
Since this case is isolated to the case when opt->check_refs_are_promisor_objects_only is true, we are confident that we are verifying the refs after downloading new data. This implies that calling reprepare_packed_git() in advance is not a huge cost compared to the rest of the operations already made.


在Git 2.35(2022年第一季度)中,将"scalar"的部分添加到contrib/中。
查看提交 ddc35d8, 提交 4582676, 提交 cb59d55, 提交 4368e40, 提交 546f822, 提交 f5f0842, 提交 9187659, 提交 829fe56, 提交 0a43fb2, 提交 cd5a9ac (2021年12月3日) 由Johannes Schindelin (dscho)完成。
查看提交 d85ada7 (2021年12月3日) 由Matthew John Cheetham (mjcheetham)完成。
查看提交 7020c88, 提交 2b71045, 提交 c76a53e, 提交 d0feac4 (2021年12月3日) 由Derrick Stolee (derrickstolee)完成。
(由Junio C Hamano -- gitster --合并于提交 62e83d4, 2021年12月21日)

scalar:实现clone子命令 Signed-off-by: Johannes Schindelin
这实现了Scalar的主观"clone"命令:它尝试使用部分克隆并默认设置稀疏检出。
git clone(man)相比,scalar clonesrc/子目录中设置工作树,鼓励源文件和构建输出之间的分离(这对Git非常有帮助,因为它避免了刷新索引时必须专门忽略的未跟踪文件)。

此外,它将存储库注册为定期维护,并根据Microsoft Windows和Microsoft Office开发团队的经验和实验配置一系列配置设置。

注意:由于"scalar clone"命令远远是最常调用的"scalar"子命令,我们将其放在手册页的顶部进行文档记录。


Git 2.36 (Q2 2022) 包括了 git scalar 的新选项:

请参阅 commit 2ae8eb5(2022 年 1 月 28 日)由 Johannes Schindelin (dscho) 提交。
(合并者为 Junio C Hamano -- gitster --commit ff6f169,2022 年 2 月 17 日)

scalar: 在子命令之前接受-C-c选项 签名:Johannes Schindelin git可执行文件有两个非常有用的选项: -C <directory>:在执行任何操作之前切换到指定目录 -c <key>=<value>:在指定标量子命令的持续时间内临时配置此设置
通过此提交,我们将这个技巧教给scalar可执行文件。
Git 2.37(2022年第三季度)引入了"scalar diagnose"子命令的实现。

查看提交 15d8adc提交 93e804b(2022年5月28日),作者为Matthew John Cheetham(mjcheetham
查看提交 0ed5b13提交 aa5c79a提交 b448557提交 de1f68a提交 237a1d1(2022年5月28日),作者为Johannes Schindelin(dscho
查看提交 23f2356(2022年5月28日),作者为Junio C Hamano(gitster
(由Junio C Hamano -- gitster --合并于提交 08baf19,2022年6月7日)

标量:实现标量诊断
签名:Johannes Schindelin
在Scalar的开发过程中,很明显有一个需要的命令,它可以收集各种有用的信息,帮助识别大型工作树/代码库中最典型的问题。
`diagnose`命令是这些艰苦得来的知识的结晶:它收集已安装的钩子、配置、描述数据形状的一些统计信息,以及其他相关信息,并将所有内容整理成一个整洁的`.zip`归档文件。
注意:最初,Scalar是使用.NET API的C#实现的,在那里我们拥有一个全面的标准库,包括编写`.zip`文件的基本功能。 在C版本中,我们没有这样的便利。 我们不想引入对libzip等库的依赖,因此我们稍微滥用了Git的`archive`机制:我们输出一个空尝试的`.zip`文件,并通过`--add-file*`选项添加了一些文件。 我们小心翼翼地尽量不修改当前代码库,以免`scalar diagnose`运行时被`diagnose`运行本身改变了导致需要运行`scalar diagnose`的情况。

使用Git 2.38(2022年第三季度),标量目标被重新表述:

参见提交 72d3a5d提交 f22c95d(2022年7月12日)由Victoria Dye(vdye
(由Junio C Hamano -- gitster --合并于提交 3a03633,2022年7月27日)

scalar:重新修改命令文档以澄清用途

签署者:Victoria Dye
确认者:Derrick Stolee

重新描述文档,将scalar描述为“大型仓库管理工具”,而不是“有偏见的管理工具”。
新的描述旨在更直接地反映scalar的实用性,以更好地指导用户准备scalar作为Git的一部分进行构建和安装。

新描述:

scalar - 一个用于管理大型Git仓库的工具

Scalar是一个仓库管理工具,它优化了Git在大型仓库中的使用,或者将现有仓库注册到Scalar中,您的Git仓库。

Scalar通过配置高级Git设置来提高性能,从而加快体验速度。
Scalar设置高级Git配置设置,后台维护仓库,并帮助减少发送的数据。


从Git 2.38(2022年第三季度)开始,将“诊断”功能从“scalar”中提取出来,并作为git bugreport的一个特性。
查看提交 43370b1, 提交 672196a, 提交 aac0e8f, 提交 7ecf193, 提交 6783fd3, 提交 33cba72, 提交 bb2c349, 提交 435a253, 提交 ba307a5, 提交 91be401, 提交 81ad551 (2022年8月12日) 由Victoria Dye (vdye)完成。
(由Junio C Hamano -- gitster --合并于提交 f00ddc9, 2022年8月25日) builtin/diagnose.c:创建 'git diagnose' 内建命令 协助者:Ævar Arnfjörð Bjarmason
协助者:Derrick Stolee
签名作者:Victoria Dye 创建一个'git diagnose'(man)内置功能,用于生成独立的存储库诊断压缩文件。
"diagnose"功能最初是为Scalar实现的,位于aa5c79a ("scalar: implement scalar diagnose", 2022-05-28, Git v2.37.0-rc0 -- merge listed in batch #8)。 然而,收集到的诊断信息并不仅适用于Scalar克隆的存储库,在诊断任何Git存储库问题时也很有用。

git diagnose现在在其手册页中包含了:

git-diagnose(1)

名称

git-diagnose - 生成诊断信息的zip归档文件

概要

[verse] 'git diagnose' [(-o | --output-directory) ] [(-s | --suffix) ]

描述

收集关于用户的机器、Git客户端和仓库状态的详细信息,并将这些信息打包成一个zip归档文件。生成的归档文件可以与Git邮件列表共享,以帮助调试问题或作为独立调试的参考。

归档文件中包含以下信息:

  • 'git version --build-options'
  • 仓库根目录的路径
  • 文件系统上可用的磁盘空间
  • 每个packfile的名称和大小,包括备用对象存储中的packfile
  • 松散对象的总数,以及按.git/objects子目录进行的统计

该工具与git bugreport不同,它收集了更多详细信息,更加关注报告仓库内容的大小和数据形状。

选项

-o <path>

--output-directory <path>

将生成的诊断归档文件放置在<path>中,而不是当前目录。

-s <format>

--suffix <format>

为诊断归档文件名称指定一个替代后缀,以创建一个名为'git-diagnostics-<formatted suffix>'的文件。这应该采用strftime(3)格式字符串的形式;当前本地时间将被使用。


它与Git for Windows 2.38(2022年10月)集成。

使用 Git 2.39(2022年第四季度),'scalar reconfigure -a' 会自动删除不再存在的 scalar.repo 条目。

查看 commit a90085b(2022年11月10日)和 commit c90db53(2022年11月7日),由 Johannes Schindelin (dscho) 提交。
(由 Junio C Hamano -- gitster -- 合并于 commit 58d80df,2022年11月23日)

scalar reconfigure -a:删除过时的scalar.repo条目 已签署:Johannes Schindelin 已签署:Taylor Blau
偶尔,Git for Windows的安装会失败,因为尝试重新配置Scalar注册失败,原因是手动删除了相应的全局Git配置中的条目。
f5f0842(“scalar:让'取消注册'优雅地处理已删除的注册目录”,2021-12-03,Git v2.35.0-rc0 - merge列在batch #4中),我们已经教会scalar delete优雅地处理手动删除的注册情况。 此补丁将相同的优雅处理添加到scalar reconfigure --all

在Git 2.40(2023年第一季度),"scalar clone" 学会了显示进度条。

请参见提交记录4433bd2(2023年1月11日)由ZheNing Hu(adlternative提交。
(由Junio C Hamano -- gitster --合并于{{link4:提交记录ebed06a},2023年1月23日)

scalar:如果stderr指向终端,则显示进度

签名:胡哲宁
确认:Derrick Stolee

有时候,当用户使用scalar下载一个具有较长提交历史的monorepo时,他们希望通过查看进度条来了解在提取过程中还需要等待多长时间,但是scalar默认情况下会抑制这个输出。

因此,让我们检查一下scalar stderr是否指向终端,如果是,则显示进度,否则禁用它。


使用 Git 2.43(2023年第四季度),scalar 包含一个选项,使用 src/ 文件夹。

查看提交 f9a547d提交 26ae8da提交 4527db8(2023年8月28日),由Derrick Stolee (derrickstolee完成。
(由Junio C Hamano -- gitster --合并于提交 19cb1fc,2023年8月29日)

scalar: 添加 --[no-]src 选项

签名:Derrick Stolee

一些用户对 Scalar 坚持将仓库放在“src”目录中持有强烈的厌恶,即使这样做可以在相邻目录中放置构建产物。

新的 --no-src 选项允许用户选择不使用默认行为。

在添加选项时,请确保 'scalar clone -h' 的使用输出与 Documentation/scalar.txt 中的 SYNOPSIS 行相同。

scalar 现在在其手册页中包含了:

--[no-]src

默认情况下,scalar clone 将克隆的存储库放置在 <entlistment>/src 目录中。使用 --no-src 将克隆的存储库直接放置在 <enlistment> 目录中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接