在服务器上重复数据删除Git分叉

Mud*_*zvi 6 linux git hardlink duplicates git-fork

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

说明:

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

/ canonical/Repo/Dev1/Repo(最初克隆时与/ canonical/Repo硬连接的对象)/ Dev2/Repo(最初克隆时硬链接到/ canonical/Repo的对象)

一切正常.问题出现在:

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

(现在,相同的'巨大'文件驻留在服务器上的开发人员的叉子上.它不会自动创建硬链接.)

这就像疯了一样吃掉了我的服务器空间!

如何在两个叉子之间重复的对象之间创建硬链接或者规范,以便保存服务器空间,并且每个开发人员从他/她的本地机器上的叉子克隆时获取所有数据?

Von*_*onC 5

\n

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

\n
\n

实际上,在 Git 2.20 中,这个问题可能会消失,因为delta island 是一种进行增量计算的新方法,这样存在于一个分叉中的对象就不会与未出现在同一分叉存储库中的另一个对象形成增量

\n

请参阅Christian Couder ( )的提交 fe0ac2f提交 108f530提交 f64ba53(2018 年 8 月 16 日)。\n帮助者:Jeff King ( )Duy Nguyen ( )。\n请参阅Jeff King的提交 9eb0986提交 16d75fa提交 28b8a73提交 c8d521f(2018 年 8 月 16 日。\n帮助者:Jeff King ( )Duy Nguyen ( )。\n (由Junio C Hamano 合并 -- --提交 f3504ea中,2018 年 9 月 17 日)chriscool
peffpclouds
peff
peffpclouds
gitster

\n
\n

添加delta-islands.{c,h}

\n
\n
\n

允许用户“分叉”现有存储库的托管提供商希望这些分叉能够共享尽可能多的磁盘空间。

\n

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

\n

这可能会使克隆或获取 fork 的速度变慢,并且占用更多的 CPU 资源,因为 Git 可能必须为许多对象计算新的增量,以避免从不同的 fork 发送对象。

\n

因为效率低下主要是当一个对象针对同一分叉中不存在的另一个对象进行增量化时出现的,因此我们将对象划分为出现在同一分叉中的集合,并定义“增量岛”。
\n在寻找Delta基地时,我们不允许将同一岛屿之外的物体视为其基地。

\n

因此,“增量岛”是一种将来自不同分叉的对象存储在同一存储库和包文件中的方法,而来自不同分叉的对象之间没有增量。

\n

该补丁实现了《》中的三角洲岛屿机制delta-islands.{c,h},但尚未使用它。

\n

struct object_entry不过,在“”中的\'\'中添加了一些新字段pack-objects.h

\n
\n

参见Documentation/git-pack-objects.txt: 三角洲岛

\n
\n

三角洲群岛

\n
\n
\n

如果可能,pack-objects尝试重用现有的磁盘增量,以避免动态搜索新增量。这是服务获取的一个重要优化,因为这意味着服务器可以完全避免膨胀大多数对象,而直接从磁盘发送字节。

\n

当对象存储为相对于接收者没有的基础(并且我们还没有发送)的增量时,这种优化不起作用。在这种情况下,服务器会“破坏”增量并必须找到一个新的增量,而这会产生较高的 CPU 成本。因此,磁盘增量关系中的对象集与客户端获取的内容相匹配对于性能非常重要。

\n

在普通的存储库中,这往往会自动工作。
\n这些对象大多可以从分支和标签访问,这就是客户端获取的内容。我们在服务器上发现的任何增量都可能存在于客户端拥有或将拥有的对象之间。

\n

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

\n

例如,假设您在单个共享对象存储中托管存储库的多个“分支”,并让客户端通过 GIT_NAMESPACE 将它们视为单独的存储库,或使用替代机制将它们视为单独的存储库。

\n

天真的重新打包可能会发现对象的最佳增量是针对仅在另一个分叉中找到的基础。
\n但是当客户端获取时,他们将没有基础对象,我们必须动态找到一个新的增量。

\n

如果您有许多外部引用refs/heads/并且refs/tags/指向相关对象(例如,refs/pullrefs/changes由某些托管提供商使用),则可能存在类似的情况。默认情况下,客户端仅获取头部和标签,并且仅在其他组中找到的对象的增量无法按原样发送。

\n

三角洲群岛通过允许您将裁判分组到不同的“岛屿”来解决这个问题

\n

APack-objects 计算从哪些岛屿可以到达哪些对象,并拒绝从对象与并非所有A岛屿中都存在的基础进行增量。这会导致包稍大一些(因为我们错过了一些增量机会),但保证了对一个岛屿的获取不会由于跨越岛屿边界而动态重新计算增量。

\n
\n
\n

但有一个副作用:有些命令更加冗长。Git 2.23(2019 年第 3 季度)修复了这个问题。

\n

请参阅Jeff King ( )提交的 bdbdf42(2019 年 6 月 20 日)。\n (由Junio C Hamano 合并 -- --提交 a4c8352中,2019 年 7 月 9 日)peff
gitster

\n
\n

delta-islands: 尊重progress国旗

\n
\n
\n

三角洲岛代码始终打印“ Marked %d islands”,即使\n进度已通过--no-progress发送 stderr 至非 tty 来抑制。

\n

让我们progress向 传递一个布尔值load_delta_islands()
\n我们已经对 中的进度表做了同样的事情resolve_tree_islands()

\n
\n
\n

在 Git 2.40(2023 年第 1 季度)中,“ git pack-objects( man )学会了在使用完 delta-island 位图数据后释放它,从而节省峰值堆内存使用量。

\n

请参阅Eric Wong ( )的提交 647982b(2023 年 2 月 3 日)。\n (由Junio C Hamano 合并 -- --提交 6d1b2e4,2023 年 2 月 9 日)ele828
gitster

\n
\n

delta-islands:免费island_marks和位图

\n

签署人:Eric Wong
\n帮助人:\xc3\x86var Arnfj\xc3\xb6r\xc3\xb0 Bjarmason
\n帮助人:Jeff King

\n
\n
\n

在我的包含 780 个岛屿的 forkgroup 镜像上linux.git,这在包对象中节省了近 4G 的堆内存。
\n这种节省只会有利于包位图的三角洲岛用户,因为否则该过程无论如何都会退出。

\n

不过,Delta island的用户可能不多,但大部分Delta island的用户也是pack bitmaps的用户。

\n
\n


Mud*_*zvi 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)
Run Code Online (Sandbox Code Playgroud)

所有分支都将在其对象/信息/替代文件中包含一个条目,该条目提供对象数据库存储库的相对路径。

将对象数据库设置为存储库非常重要,因为我们可以保存具有相同名称的存储库的不同用户的对象和引用。

脚步:

  1. git init --bare shared-object-database.git
  2. 每次推送到任何分叉(通过接收后)或运行 cronjob 时,我都会运行以下代码行

    for r in list-of-forks
        do
    
    Run Code Online (Sandbox Code Playgroud)

    ( cd "$r" && git Push ../shared-objects-database.git "refs/ :refs/remotes/$r/ " && echo ../../shared-objects-database.git/objects >objects /info/alternates # 为了保存,我每次都将“胖”对象添加到替代项中)完成

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

git repack -adl也是一种选择!

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

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

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

(我终于找到了一个适合我的解决方案!(未在生产中进行测试!:p 感谢这篇文章。)