有没有办法硬链接包含多个Git存储库的文件夹中的所有重复对象?
说明:
我在公司服务器(Linux机器)上托管Git服务器。 我们的想法是拥有一个主要的规范存储库,每个用户都没有对其进行推送访问,但每个用户都会使用规范存储库(将规范克隆到用户的主目录,从而实际创建硬链接)。
/规范/回购 / Dev1 / Repo(最初克隆时硬链接到/ canonical / Repo的对象) / Dev2 / Repo(最初克隆时与/ canonical / Repo硬链接的对象)
一切正常。问题出现在:
Dev1:将巨大的提交推送到服务器上的fork(/ Dev1 / Repo)Dev2: 在他的本地系统上获取,进行自己的更改并推送它 到他自己的服务器分叉(/ Dev2 / Repo)
(现在同样的'巨大'文件驻留在服务器上的开发人员的叉子上。它不会自动创建硬链接。)
这就像疯了一样吃掉了我的服务器空间!
如何在两个叉子之间重复的对象之间创建硬链接或者规范,以便保存服务器空间,并且每个开发人员在他/她的本地计算机上从他/她的分支克隆时都会获得所有数据?
答案 0 :(得分:3)
我决定这样做:
shared-objects-database.git/
foo.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
bar.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
baz.git/
objects/info/alternate (will have ../../shared-objects-database.git/objects)
所有的分叉都会在其对象/信息/替代文件中有一个条目,该文件提供了对象的相对路径。数据库存储库。
将对象数据库设置为存储库非常重要,因为我们可以保存具有相同名称存储库的不同用户的对象和引用。
步骤:
git init --bare shared-object-database.git
每次推送任何fork(通过post-recieve)或运行cronjob时,我都运行以下代码行
for r in list-of-forks
do
( cd" $ r" &安培;&安培; git push ../shared-objects-database.git" refs / :refs / remotes / $ r / " &安培;&安培; echo ../../shared-objects-database.git/objects> objects / info / alternates #要保存我添加"脂肪"每次交替的对象 ) 完成
然后在下一个" git gc"将删除备用中已存在的叉中的所有对象。
git repack -adl
也是一种选择!
这样我们就可以节省空间,以便两个用户在服务器上推送相应数据的相同数据共享对象。
我们需要在共享对象数据库中将gc.pruneExpire
变量设置为never
。为了安全起见!
偶尔修剪对象,将所有分支作为遥控器添加到共享,获取和修剪! Git会做其余的事情!
(我终于找到了一个适合我的解决方案!(未在生产中测试过!:p感谢this post。)
答案 1 :(得分:2)
现在,相同的“巨大”文件驻留在服务器上两个开发人员的fork中。它不会自动创建硬链接
实际上,在Git 2.20中,由于 delta岛,该问题可能会消失,这是一种进行增量计算的新方法,因此,一个分叉中存在的对象不会变成一个相对于未出现在同一个分支存储库中的另一个对象的差异。
请参见commit fe0ac2f的commit 108f530,commit f64ba53,Christian Couder (chriscool
)(2018年8月16日)。
帮助者:Jeff King (peff
)和Duy Nguyen (pclouds
)。
请参见commit 9eb0986的commit 16d75fa,commit 28b8a73,commit c8d521f,Jeff King (peff
)(2018年8月16日)。
帮助者:Jeff King (peff
)和Duy Nguyen (pclouds
)。
(由Junio C Hamano -- gitster
--在commit f3504ea中合并,2018年9月17日)
添加
delta-islands.{c,h}
允许用户“分叉”现有存储库的托管服务提供商希望这些分叉共享尽可能多的磁盘空间。
替代方案是一种现有解决方案,用于将所有分支中的所有对象都保留在唯一的中央存储库中,但这可能会有一些缺点。
特别是在打包中央存储库时,将在不同派生的对象之间创建增量。由于Git可能必须为许多对象计算新的增量以避免从其他fork发送对象,因此这会使克隆或获取fork的速度变慢,并且占用大量CPU的资源。
由于效率低下主要是由于将一个对象针对同一分支中不存在的另一个对象进行删除而引起的,因此我们将对象划分为出现在同一分支中的集合,并定义“增量岛”。
找到增量基准时,我们不允许将同一岛外的对象视为基准。因此,“增量岛”是一种将来自不同分支的对象存储在同一存储库和packfile中的方法,而不会导致来自不同分支的对象之间存在差异。
此修补程序在“
delta-islands.{c,h}
”中实现了增量孤岛机制,但尚未使用。不过,“
struct object_entry
”的“pack-objects.h
”中添加了一些新字段。
请参见Documentation/git-pack-objects.txt
: Delta Island:
DELTA ISLANDS
在可能的情况下,
pack-objects
尝试重用现有的磁盘增量,以避免在运行中立即寻找新的增量。对于服务提取来说,这是一项重要的优化,因为这意味着服务器可以完全避免膨胀大多数对象,而直接从磁盘发送字节。当对象作为增量存储在对象没有接收者(并且我们尚未发送)的基准上时,此优化将无法进行。在这种情况下,服务器会“破坏”增量并不得不找到一个新的增量,这会带来很高的CPU成本。因此,对磁盘增量关系中的对象集进行匹配对于性能至关重要 客户会得到什么。
在普通存储库中,这往往会自动运行。
这些对象大多数都可以从分支和标签访问,而这正是客户端获取的对象。我们在服务器上发现的任何增量都可能在客户端拥有或将要拥有的对象之间。但是在某些存储库设置中,您可能有几个相关但独立的参考提示组,客户端倾向于独立获取这些组。
例如,假设您在单个共享库中托管一个存储库的多个“分支”,并允许客户端通过GIT_NAMESPACE将它们视为独立的存储库,或使用替代机制将其视为独立的存储库。
幼稚的重新打包可能会发现某个对象的最佳增量与仅在另一个fork中找到的基准相对。
但是,当客户端获取数据时,它们将没有基础对象,我们将不得不动态查找新的增量。如果您在
refs/heads/
和refs/tags/
之外有很多引用指向相关对象(例如,某些托管服务提供商使用的refs/pull
或refs/changes
)的引用,则可能存在类似情况)。默认情况下,客户端仅获取标头和标签,并且仅能按原样发送针对仅在其他组中找到的对象的增量信息。三角洲岛屿允许您将裁判分为不同的“岛屿”来解决此问题。
打包对象计算从哪个岛可以到达哪些对象,并拒绝根据
A
的所有岛中都不存在的基准从对象A
得出增量。这样会导致包的数量稍大一些(因为我们错过了一些三角洲机会),但可以保证获取一个岛屿不会因为跨越岛屿边界而即时重新计算三角洲。