2012-10-12 57 views
10

我有一個存儲庫,用於存儲一些增長非常大的大型二進制文件(tifs,jpgs,pdfs)。還有相當數量的文件被創建,刪除和重命名,我不關心個人提交歷史記錄。這個問題有點簡單,因爲我正在處理一個沒有分支和標籤的倉庫。從git存儲庫中刪除舊的提交信息,以節省空間

我很好奇,如果有一種簡單的方法可以從系統中刪除一些歷史記錄以節省空間。

我發現了一個古老的線程on the git mailing list,但它並沒有真正說明如何使用這個(即$下降是什麼):

git filter-branch --parent-filter "sed -e 's/-p $drop//'" \ 
     --tag-name-filter cat -- \ 
     --all ^$drop 
+0

好奇,從你的10Gb項目文件,你能節省多少空間? 2MBS? 25MB還是像200Mgb? – Honey

+0

在我的情況下,存儲庫中90%的文件仍然需要,所以它只能節省10%的空間。 – greggles

+0

你的意思是你保存了1Gb?!或10%與git相關的元數據?這是多少? – Honey

回答

8

我想,你可以縮小你的歷史以下這樣的回答:

How to delete a specific revision of a github gist?

決定其在歷史上指出,要保持。

pick <hash1> <commit message> 
pick <hash2> <commit message> 
pick <hash3> <commit message> <- keep 
pick <hash4> <commit message> 
pick <hash5> <commit message> 
pick <hash6> <commit message> <- keep 
pick <hash7> <commit message> 
pick <hash8> <commit message> 
pick <hash9> <commit message> 
pick <hash10> <commit message> <- keep 

然後,在每個「保持」作爲「挑選」後留下第一個,並將其他標記爲「壓扁」。

pick <hash1> <commit message> 
squash <hash2> <commit message> 
squash <hash3> <commit message> <- keep 
pick <hash4> <commit message> 
squash <hash5> <commit message> 
squash <hash6> <commit message> <- keep 
pick <hash7> <commit message> 
squash <hash8> <commit message> 
squash <hash9> <commit message> 
squash <hash10> <commit message> <- keep 

然後,通過保存並退出編輯器來運行rebase。在每個「保持」點,消息編輯器將彈出一個組合的提交消息,從前面的「選擇」到「保持」提交。然後,您可以保留最後一條消息,或者將這些消息結合起來記錄原始歷史記錄,而不必保留所有中間狀態。

重新綁定之後,中間文件數據仍將存儲在存儲庫中,但現在未被引用。 git gc現在確實會讓你擺脫這些數據。

+0

這似乎可能是有幫助的,如果我只是壓縮每一個提交(或X日期之前的每一個提交),但這似乎很乏味。有沒有更自動的方式來做到這一點? – greggles

+0

另外,我的整個目標是節省磁盤空間,所以我想知道是否有一些統計數據表明,在大型回購(〜10GB相對較大的文件)中可以節省多少空間。如果我只是刪除元數據,但沒有關於刪除對象的信息,那麼我認爲這沒有多大幫助。 – greggles

+1

通過刪除提交,您將刪除元數據和對樹數據的引用。如果這意味着最後一個引用被刪除(沒有其他提交引用特定內容),則在下一個'gc'上刪除實際有效負載。例如,如果你正在壓縮從添加一個給定文件到提交再次被刪除的所有提交,那麼文件數據實際上將被放在'gc'上。 –

6

你總是可以直接刪除.git,做一個新鮮git --init一個初始提交。這當然會刪除所有的提交歷史記錄。

+0

是的,絕對考慮到這是一個簡單但很激烈的選擇。我將歸檔.git回購,然後執行此操作。我希望有些東西不那麼激烈:) – greggles

+0

'git init'。爲什麼'--init'? –

+1

基本上: 'move .git/somewhere/else; git init; git add。; git commit -m「初始提交」; git add origin [repoUrl]; git push origin --force' –

3

$下降是一個變量(您想尋找)

如果要清理不必要的文件和優化本地資源庫中,你必須檢查命令git gc

而且git prune是另一種選擇,因爲它刪除任何可達分支中的任何對象不再指向的對象。

我希望這可以幫助你。

+0

這不適用於任何仍在歷史中的對象,這就是我認爲問題提到的內容。 –

+0

這些看起來很有幫助,但我仍然對如何使用該命令感到困惑(例如,哪些參數需要調整以保留更多或更少的歷史記錄)。 – greggles

+0

「git gc」調用「git prune」。看到https://git-scm.com/docs/git-prune#_notes – Hackless

1

如果你想從你的Git歷史記錄中找到並刪除大文件,Pro Git有一個名爲Removing Objects的部分,它指導你完成這個過程。這有點複雜,但它可以讓你從歷史記錄中刪除已刪除的文件,同時保持歷史記錄的其餘部分不變。

0

讓git忘記一個文件有點複雜。

git rm只會從現在開始刪除這個分支上的文件,但它仍然在歷史中,git會記住它。

正確的做法與git filter-branch一樣,正如其他人在此提到的。它會重寫分支歷史記錄中的每個提交以刪除該文件。

但是,即使這樣做後,git可以記住它,因爲可以在reflog,遙控器,標籤等中引用它。

我寫了一個叫git forget-blob

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

的小工具,這是很容易,只是做git forget-blob file1.txt

這將刪除每個引用,做git filter-branch,最後運行git垃圾回收器git gc完全擺脫這個文件在你的回購。