2016-05-09 188 views
0

動機:我有一個有點特定的場景,對此Git似乎很適合,但它仍然不足以需要一些特定的工作。基本上它是一堆文本文件(無代碼),它們至少每10秒鐘會自動更新一次。這些變化可能相當大,至少隨着時間的推移,知識庫的規模會變得相對較大。本地存儲庫位於嵌入式系統中,沒有固定的網絡連接,所以自然的工作流程是在本地收集提交,在有機會時推送它們,然後刪除剛推出的內容以釋放空間(如有必要)。歷史記錄可能對暫時保留設備有用,但最重要的是應該可以將其從設備中刪除。 (它永遠保存在遙控器上)。根據一些特定於應用程序的因素,情況可能會有所擴展,我們可能會利用git中的其他功能,但我概述的基本結構應保持不變。Git:'永久刪除'(分支)沒有rebase或過濾分支

更具體地說,存儲庫和一個遠程存在一個本地副本,並且本地只向遠程推送(特定分支)(從不拉)。提交圖很簡單,一個接一個提交的「直線」,沒有合併或平行線。只要有機會推動(如上所述),就會爲更多的提交創建一個新的分支。所以每隔一段時間我們都會有一個新的分支,它基本上只是用來組織提交的時間表。除此之外,我們從不改變分支。

因此,舊的分支可以刪除,正如討論這是我們的目標,尤其是當空間成爲一個問題。要「永久刪除」的提交和分支,我們嘗試了以下內容:

 
date=$(date +"%m-%d-%y--%H-%M-%S") 

git $opt checkout -b "$date" 

git $opt branch -d $to_push 

# the first commit will be the single 'initial' commit in the master 
# branch, which is permanent and never 'deleted' 
git $opt replace --graft \ 
    $(git $opt log -n 1 --pretty="%H") \ 
    $(git $opt rev-list --max-parents=0 HEAD) 

git $opt reflog expire --expire=now --all 
git $opt gc --aggressive --prune=now 
git $opt repack -a -d -l 

的選擇變量只是指定的工作樹和git目錄。我們執行的移植(使用隨後的gc等)成功地消除了天真git log的提交,並且確實釋放了一些空間,但它似乎並沒有釋放「仍由提交中保存的差異」佔用的空間「 ;例如,創建,提交併刪除的大文件在以這種方式消除其提交後仍將繼續佔用空間。我們在實踐中不會有任何特別大的文件,但是我認爲這種行爲更一般,因爲'來自變化的數據'(差異?)仍然保存在存儲庫中,或類似的東西,這就是我們關心消除。

我設法將剩下的結構向下拖動,並向我建議了一些技巧,例如從配置中的'fetch'glob中移除分支並運行git fetch --prune origin;例如git update-ref -d refs/remotes/origin/05-07-16--15-48-59,但這並未釋放相關空間。下面的數據描述了倉庫的狀態,因爲它目前爲:

 
$ git log --all --oneline --graph --decorate 
* de345b6 (HEAD -> 05-07-16--15-50-56, replaced) sam. mai 7 15:44:16 EDT 2016 
| * 50272b5 sam. mai 7 15:44:16 EDT 2016 
|/ 
| * 0b96272 sam. mai 7 15:29:48 EDT 2016 
|/ 
| * b764118 sam. mai 7 15:28:13 EDT 2016 
|/ 
| * efa0536 sam. mai 7 15:14:45 EDT 2016 
|/ 
| * 40c8806 sam. mai 7 15:13:57 EDT 2016 
|/ 
| * 6f7c2f9 sam. mai 7 15:12:26 EDT 2016 
|/ 
| * fa33771 sam. mai 7 15:11:21 EDT 2016 
|/ 
| * 8698acd sam. mai 7 15:11:08 EDT 2016 
|/ 
* b2d9486 (origin/master, master) initial 
 
$ git show-ref 
de345b670e24ac68bbbf4aa7efd22598ef3c7251 refs/heads/05-07-16--15-50-56 
b2d9486d5d427d1ae4bb88828f334454a2fb6954 refs/heads/master 
b2d9486d5d427d1ae4bb88828f334454a2fb6954 refs/remotes/origin/master 
0b96272e47cab0b29e2706cae83b8154f8e412ea refs/replace/0afdaca4e6d071fc026d209249a7b0532c11122a 
b7641184c898ff08917d363435d5f45e5e9664ed refs/replace/498f8846c6a742f96997b599f5e25f5ad20b568c 
6f7c2f9b7700b39b4fd837c34ab7911a08d5438a refs/replace/4df4f9cf8cc01500c800f3f04cbbd655a866c9ba 
8698acd667d406fab764389b87518d133de887a6 refs/replace/9a91b7248da808a9fc6e1531c4206a6865273005 
40c880617db664cb73390d90e1401a049bc8c303 refs/replace/9edc1e243f4f36034a800c566fdeeac511e077a3 
efa0536a40e68d92751193fa0c6dec502d77ce72 refs/replace/d6256dbe48a10461e17ca3cf7e7c40700937d249 
fa3377117750fd81c703519038268fec89b65dce refs/replace/db9923391013d8e5d2974f328037f6315af85783 
50272b55f66b8d7c55305a3502db8e9f88b2db03 refs/replace/de345b670e24ac68bbbf4aa7efd22598ef3c7251 

關於在主題中提到的標準,我們不想做一個rebasefilter-branch因爲在工作樹中的數據是正如所討論的那樣經常更新和更新。我想我們可以在其他地方複製工作樹,然後在那裏執行刪除操作,但是這會進一步加劇空間限制。即使我們在其他地方複製了它,併成功使用rebase或filter-branch刪除了舊數據,我們也需要rsync將實時存儲庫中的所有新更改複製到複製的存儲庫中,並將複製的存儲庫複製到活動存儲庫中,全部對於正在積極地從存儲庫中讀取和/或修改存儲庫內容的過程是原子性的,這似乎是不必要的麻煩,但是我們對它開放。

我們給出的另外一個建議是使用format-patcham'序列化'提交併在以文本文件補丁的形式傳輸它之後重建遠程存儲庫上的結構。然後,我們可以在本地創建一個新的存儲庫來擺脫舊數據。但是這聽起來也不必要的複雜,基本上就像是重新開始git設計的工作。我們願意接受這種可能性(或者爲此可能切換到另一個VCS,或者是定製的東西),但看起來我們正在接近實現這個目標,而git似乎很適合我們的用例。

我可以提供更多詳細信息,並且我還可以重新創建存儲庫並在過程的各個步驟嘗試不同的步驟和/或顯示命令輸出。謝謝你的時間。

編輯

吸血鬼的建議後,他要求補充資料:

 
$ git rev-list --all | xargs -l $git describe --all --always    
replace/de345b670e24ac68bbbf4aa7efd22598ef3c7251 
replace/0afdaca4e6d071fc026d209249a7b0532c11122a 
replace/498f8846c6a742f96997b599f5e25f5ad20b568c 
replace/d6256dbe48a10461e17ca3cf7e7c40700937d249 
replace/9edc1e243f4f36034a800c566fdeeac511e077a3 
replace/4df4f9cf8cc01500c800f3f04cbbd655a866c9ba 
replace/db9923391013d8e5d2974f328037f6315af85783 
replace/9a91b7248da808a9fc6e1531c4206a6865273005 
heads/05-07-16--15-50-56 

回答

1

你的問題是,你使用git replace
git replace使git假裝一個提交實際上是另一個提交或在你的情況下,一個提交的父母是另一個提交的父母。
但是原始對象仍然存在,它們只是在邏輯上替換爲大多數git命令,但在物理上不會被替換,除非您使用rebasefilter-branch或類似的方法進行替換。

但是,如果我沒有得到你錯了,你真的是以後有什麼是簡單如下:

git reset --soft <initial commit> 
git commit -m "recording current state as the only commit after the initial commit" 

,然後再打包和東西消滅垃圾

你甚至可以東西這兩個命令在一個git別名中,讓我們在Git中進行原子操作,據我所知。

+0

感謝您的回覆。不幸的是,這似乎並沒有減少庫的大小,後來的提交仍然出現在'log --all --oneline --graph --decorate'中。我還應該注意''git reflog expire --expire = now all'會給出'錯誤:所有點都無處!',這在之前已經發生了,而且我忘了在我的帖子中提到(我將添加它)。如果您認爲我當前的測試存儲庫可能存在特定問題,則可以創建一個新的測試存儲庫並在該位置嘗試。 –

+0

我想你在'all'前面''',所以'--all'而不是'all'。否則,只會將名爲'all'的分支的reflog過期,因爲錯誤提示沒有指向任何位置。 – Vampire

+0

哦對不起,是的,這應該是顯而易見的。隨着reflog過期以及隨後的gc和重新包裝,我的體積從120M降至80M。什麼可以佔用額外的空間?我會認爲它會全部或沒有。 –