截断git存储库保留常规快照

截断git存储库保留常规快照,git,backup,archive,Git,Backup,Archive,我想跟踪一个500kb的json文本,它每分钟都会更改内容。我想使用git,因此我可以在另一台服务器上使用git pull来下载该文件的最新版本,而不会出现问题,该文件在下载过程中可能会发生更改,同时我还希望以这种方式对该文件的最后几个月/几年进行版本控制 我曾想过创建一个git存储库,在其中提交每个文件更改,但我注意到,几天后,这个存储库的大小达到了很多GB(即使使用git gc,因为文件中的更改太多了) 我可以定期将git截断到特定的深度,但这不是我需要的。我需要这些信息,一周前、一个月前、

我想跟踪一个500kb的json文本,它每分钟都会更改内容。我想使用
git
,因此我可以在另一台服务器上使用
git pull
来下载该文件的最新版本,而不会出现问题,该文件在下载过程中可能会发生更改,同时我还希望以这种方式对该文件的最后几个月/几年进行版本控制

我曾想过创建一个git存储库,在其中提交每个文件更改,但我注意到,几天后,这个存储库的大小达到了很多GB(即使使用
git gc
,因为文件中的更改太多了)

我可以定期将git截断到特定的深度,但这不是我需要的。我需要这些信息,一周前、一个月前、一年前文件的样子。虽然我不需要那么多的承诺,但在过去时间越长

使用git和一些bash魔法,这可能吗?我可以删除并重新创建存储库,并在该git中使用
--amend


或者你会建议另一种解决方案吗?

至少有一种方法可以做到这一点;我将在下面概述一种方法。首先要考虑几件事:

根据发生的更改的性质,您可能希望查看频繁打包数据库是否有帮助;git非常擅长避免浪费空间(至少对于文本文件)

当然,对于您描述的提交负载—每天1440次提交,是给予还是索取?-历史将趋于发展。尽管如此,除非每次提交时都有显著的变化,否则它似乎可以比“几天内的许多GB”做得更好;而且,您可能会达到一个折衷归档战略变得切实可行的程度

关于“我需要保存的所有数据”是否比“我需要定期访问的所有数据”更大,也总是值得思考的;因为这样你就可以考虑一些数据是否应该保存在存档中,可能是在某种形式的备份介质上,而不是作为活期回购的一部分。 正如你在你的问题中提到的,你可能想考虑Git是否是这项工作的最佳工具。您描述的用法没有使用git的大部分功能;它也没有实现真正让git出类拔萃的功能。相反,其他工具可能更容易逐步淡化历史

但尽管如此,您仍然可能会决定从“每分钟”数据开始,然后最终将其降低到“每小时”,然后再降低到“每周”

(我不建议定义太多的粒度级别;最“划算”的方法是放弃每小时一次的快照。小时->天将是边界,天->周可能会浪费时间。如果你开始每周,这肯定足够稀疏了……)

因此,当一些数据“过期”时,该怎么办?我建议您可以结合使用重定基址(和/或相关操作)、深度限制和替换(取决于您的需要)。根据您如何组合这些,您可以在不更改任何“当前”提交的SHA ID的情况下保持无缝历史的假象。(使用更复杂的技术,您甚至可以安排从不更改SHA ID;但这显然更难,并且会在一定程度上减少空间节省。)

因此,在下图中,有一个根提交标识为“O”。后续提交(每分钟的更改)由字母和数字标识。字母表示创建提交的日期,数字按顺序标记分钟

您创建初始提交,并根据最终使用的每个历史粒度在其上放置分支。(随着每分钟更改的累积,它们将继续进行
master

这给了你

O <-(weekly)
|\
| A60' - A120' - ... - A1380' - A1440' <-(hourly)
 \
  A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1 <--(master)
或者在这种情况下(由于
A1440
A1440'
处的
是相同的),这相当于重新创建
B1
的父级-有关该方法的详细信息,请参阅
git筛选器分支
文档

O <-(weekly)
|\
| A60' - A120' - ... - A1380' - A1440' <-(hourly)
|                                     \
|                                      B1' - B2' - ... - B1439' - B1440' - C1' <-(master)
 \
  A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1

不过,这也有一些缺点。替换存在一些已知的怪癖。此外,在这种情况下,原始提交并非不可访问(即使默认情况下未显示);您必须将
master
分支变浅以清除它们。将分支变浅的最简单方法是克隆回购,但随后您必须跳转额外的环以传播替换的引用。因此,如果您永远不希望
master
ref“实现”,则这是一个选项"它以一种不正常的方式移动,但不是那么简单。

一组每分钟/小时/天/月触发一次的
cron
作业是否是一个有效的解决方案?我怀疑
git
解决方案太过工程化,特别是考虑到每次尝试截断存储库时,都需要每小时重新计算一次你试过运行
git-gc
git-gc--aggressive
来看看你的git-repo可以缩减多少吗?我想使用git,这样我就可以在另一台服务器上使用git-pull来下载该文件的最新版本,而不会出现问题,文件在下载过程中可能会发生变化,我还想对该文件进行版本控制t以这种方式同时归档过去几个月/几年
git checkout hourly
git merge --squash A60
git commit -m 'Day A 1-60'
git merge --squash A120
git commit -m 'Day A 61-120'
...
O <-(weekly)
|\
| A60' - A120' - ... - A1380' - A1440' <-(hourly)
 \
  A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1 <--(master)
git rebase --onto A1440' A1440 master
O <-(weekly)
|\
| A60' - A120' - ... - A1380' - A1440' <-(hourly)
|                                     \
|                                      B1' - B2' - ... - B1439' - B1440' - C1' <-(master)
 \
  A1 - A2 - A3 - ... - A1439 - A1440 - B1 - B2 - ... - B1439 - B1440 - C1
git replace A1440 A1440'