2017-09-11 42 views
0

我想跟踪一个500kb的json文本,它能够很快地改变它的内容。我想使用git,所以我可以在另一台服务器上使用git pull来下载该文件的最新版本,而不会出现问题,该文件可能在下载过程中发生更改,并且我还希望在最近几个月内对该文件进行版本控制/年同时这种方式。truncate git repository keepinng定期快照

我想创建一个Git仓库,我提交的每个文件的变化,但我注意到,过了些日子,这个仓库获得许多GB的大小(甚至git gc,因为文件中的变化这么多)

我可以定期将git截断到特定深度,但这不是我所需要的。我需要的信息,一个星期前,一个月前,一年前如何看起来像。尽管过去我不需要那么多的承诺。

这甚至可能与Git和一些bash魔法?我很好,删除和重新创建存储库,并在该git中使用--amend

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

+0

是否每分钟/小时/天/月触发一个适当的'cron'作业是一个有效的解决方案?我怀疑'git'解决方案太过于工程化了,尤其是考虑到每次尝试截断存储库时,都需要重新计算其中的每一个散列值。 – Phylogenesis

+0

您是否尝试过运行'git gc'或'git gc --aggressive'来查看您的git repo可以缩小多少? – Mort

+0

我想使用git,所以我可以在另一台服务器上使用git pull来下载该文件的最新版本而不会出现问题,该文件可能在下载过程中发生更改,并且我还希望对该文件进行版本控制几个月/年这种方式在同一时间 – rubo77

回答

1

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

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

当然,你提到的提交负载 - 每天1440次提交,给与否? - 历史将趋于增长。尽管如此,除非每次提交的变化都很显着,否则似乎可以比“几天内的多GB”更好。也许你会达到妥协存档策略变得切实可行的水平。

关于“我需要保留的所有数据”是否大于“我需要经常访问的所有数据”,这总是值得思考的;因为那时你可以考虑一些数据是否应该保存在归档仓库中,可能在某种形式的备份媒体上,而不是作为活动仓库的一部分。

而且,正如你提到你的问题,你可能想考虑git是否是最好的工具。你描述的用法不使用大部分git的功能;也不会执行真正使git excel的功能。相反,其他工具可能会使逐渐减少历史记录变得更容易。

但所有这一切说,你还是可能会达到下手“每分钟”的数据,然后最终下降到“每小时”的决定,也许再后来减少到*每周”。

(我不鼓励定义很多级别的粒度;最“爆炸你的钱”将随着丢弃子时间快照而出现,小时 - >日将是临界,日 - >星期可能会浪费。如果你一周下来,这肯定是足够稀疏......)

所以当一些数据“老化”,该怎么办?我建议你可以使用我的重新组合(和/或相关操作),深度限制和替换(取决于您的需求)。根据你如何组合这些,你可以保持无缝历史的幻觉而不用改变任何“当前”提交的SHA ID。(对于更复杂的技术,你甚至可以安排从未改变SHA ID,但是这是明显的困难,并会有所减少空间的节省。)

所以在下面的图中,有提交认定为根'O'。后续提交(每分钟更改)由字母和数字标识。该字母表示提交创建的那一天,数字顺序标记分钟。

您可以创建初始提交,并为其最终使用的每个历史粒度放置分支。 (由于积累的变化每分钟,他们就会去master

O <--(master)(hourly)(weekly) 

后一两天你

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

也许你已经决定,在午夜,任何子小时24小时的快照可以被丢弃。

因此,当天C开始时,A快照超过24小时,应该缩减为小时快照。首先,我们必须创建每小时快照

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) 

这里A1440'A1440重写,但使用不同的血统(使得它的直接父是“一个小时前”而不是“一分钟前”)。

接下来,为了使历史无缝,您将有B1确定A1440'作为其父项。如果你不关心改变每次SHA ID提交(包括当前的),衍合会工作

git rebase --onto A1440' A1440 master 

或在这种情况下(因为TREE s的A1440A1440'是相同的)它会相当于重新编号B1 - 请参阅git filter-branch文档了解该方法的详细信息。无论哪种方式,你会最终

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

需要注意的是,即使在BC提交更改的粒度是不变的,这仍然是“改写”提交(因此'符号);而实际上原始提交还没有被物理删除。但它们无法到达,因此最终会被gc清除;如果这是一个问题,您可以通过放弃24小时以上的reflog,然后手动运行gc来加速实现。

或者,如果您要保留SHA ID为BC提交,您可以使用git replace

git replace A1440 A1440' 

虽然这有许多缺点。有几个已知的替代品怪癖。同样在这种情况下,原始提交不可达(即使它们没有默认显示);你将不得不浅浅master分支摆脱它们。浅化分支最简单的方法是克隆回购,但是你必须跳过额外的箍来传播替代参考。因此,如果您不希望master参考“意识到”它以异常方式移动,但这并不简单,那么这是一个选项。