Linux 服务器上的重复数据消除Git分叉

Linux 服务器上的重复数据消除Git分叉,linux,git,duplicates,git-fork,hardlink,Linux,Git,Duplicates,Git Fork,Hardlink,有没有办法硬链接包含多个Git存储库的文件夹中的所有重复对象 说明: 我在公司服务器(Linux机器)上托管一个Git服务器。 其想法是拥有一个主规范存储库,每个用户都没有对其进行推式访问的权限,但每个用户都会将规范存储库分叉(将规范克隆到用户的主目录,从而实际创建硬链接) /规范/回购 /Dev1/Repo(最初克隆时硬链接到/canonical/Repo的对象) /Dev2/Repo(最初克隆时硬链接到/canonical/Repo的对象) 这一切都很好。问题出现在: Dev1:将一个巨大的

有没有办法硬链接包含多个Git存储库的文件夹中的所有重复对象

说明:

我在公司服务器(Linux机器)上托管一个Git服务器。 其想法是拥有一个主规范存储库,每个用户都没有对其进行推式访问的权限,但每个用户都会将规范存储库分叉(将规范克隆到用户的主目录,从而实际创建硬链接)

/规范/回购 /Dev1/Repo(最初克隆时硬链接到/canonical/Repo的对象) /Dev2/Repo(最初克隆时硬链接到/canonical/Repo的对象)

这一切都很好。问题出现在:

Dev1:将一个巨大的提交推送到服务器上的fork(/Dev1/Repo)Dev2: 在他的本地系统上获取它,进行自己的更改并推动它 到他自己的服务器上的fork(/Dev2/Repo)

(现在,同一个“巨大”文件驻留在服务器上开发人员的两个分叉中。它不会自动创建硬链接。)

这正在疯狂地吞噬我的服务器空间


我如何在两个fork或canonical之间重复的对象之间创建硬链接,以便节省服务器空间,并且每个开发人员从其本地计算机上的fork克隆时获得所有数据?

我决定这样做:

 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)
所有fork在其objects/info/alternates文件中都有一个条目,该条目提供了对象数据库存储库的相对路径

使对象数据库成为存储库很重要,因为我们可以保存具有相同名称存储库的不同用户的对象和引用

步骤:

  • git init——裸共享对象数据库.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 #为了保存,我每次都将“fat”对象添加到alternates中 ) 完成

  • 然后在下一个“git gc”中,forks中已经存在于alternate中的所有对象都将被删除

    git-repack-adl
    也是一个选项

    通过这种方式,我们节省了空间,以便两个用户在服务器上各自的fork上推送相同的数据,从而共享对象

    我们需要在共享对象数据库中将
    gc.prueexpire
    变量设置为
    never
    。只是为了安全

    要偶尔修剪对象,请将所有分叉作为远程对象添加到共享、获取和修剪中!Git会做剩下的事

    (我终于找到了适合我的解决方案!(未在生产中测试!:p感谢。)

    现在,同样的“巨大”文件驻留在服务器上开发人员的两个分支中。它不会自动创建硬链接

    实际上,在Git 2.20中,这个问题可能会消失,因为delta孤岛,这是一种新的delta计算方法,使得存在于一个fork中的对象不会与不在同一个fork存储库中的另一个对象形成delta

    参见(2018年8月16日)作者。
    帮助人:、和。
    参见,,(2018年8月16日)作者。
    帮助人:、和。
    (于2018年9月17日被合并)

    添加
    delta岛。{c,h}
    允许用户“分叉”现有存储库的托管提供商希望这些分叉共享尽可能多的磁盘空间

    Alternates是一种现有的解决方案,用于将所有分支中的所有对象保存到唯一的中央存储库中,但这可能有一些缺点。
    特别是在打包中央存储库时,将在来自不同分支的对象之间创建增量

    这可能会使克隆或获取fork的速度慢得多,CPU占用也大得多,因为Git可能需要为许多对象计算新的增量,以避免从不同的fork发送对象

    由于效率低下主要是在一个对象与不存在于同一分叉中的另一个对象进行deltified时产生的,因此我们将对象划分为出现在同一分叉中的集合,并定义“delta岛”。
    在寻找三角洲基地时,我们不允许将同一岛屿外的物体视为其基地

    因此,“delta islands”是一种将来自不同分支的对象存储在同一存储库和打包文件中的方法,不同分支的对象之间没有delta。

    此修补程序在“
    delta-islands.{c,h}
    ”中实现了delta-islands机制,但尚未使用它

    不过,在“
    pack objects.h
    ”中的“
    struct object”条目中添加了一些新字段

    见:

    三角洲群岛 在可能的情况下,
    pack objects
    尝试重用现有磁盘上的增量,以避免不停地搜索新的增量。这对于服务抓取来说是一个重要的优化,因为这意味着服务器可以完全避免膨胀大多数对象,而只需直接从磁盘发送字节

    当对象以增量形式存储在接收方没有的基础上(并且我们还没有发送),这种优化就无法工作。在这种情况下,服务器“中断”增量和必须找到一个新的增量,这需要很高的CPU成本。因此,磁盘上增量关系中的对象集匹配对于性能非常重要 客户会得到什么

    在普通存储库中,这往往会自动工作。
    这些对象大多可以通过分支和标记访问,这也是客户端获取的。我们在服务器上找到的任何增量都可能位于客户端拥有或将拥有的对象之间

    但在某些存储库设置中,您可能有几个相关但独立的ref提示组,客户机倾向于独立获取这些组