2017-09-11 74 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參考「意識到」它以異常方式移動,但這並不簡單,那麼這是一個選項。