2015-09-08 40 views
1

我一直在試圖編寫了涉及把下面的代碼post-receive git的鉤一個實驗:git gc:垃圾收集是否在post-receive中被禁用?

unset GIT_DIR 
cd (path to some temp directory outside the repository) 
git clone --local (path to repository just pushed to) . 
git checkout dev 
git reset --hard HEAD^ 
git reflog expire --expire=now --all 
git gc --aggressive --prune=now 

基本上我做的是克隆剛被推到了倉庫,做一個硬復位刪除最後一次提交,然後執行垃圾收集以刪除歷史記錄中最後一次提交的痕跡。要檢查垃圾收集是否真的在做它的工作,我在最後一次提交中提交了一個巨大的4 MB文件,然後檢查.git的大小以查看它是否已被刪除。

因此,當我在git「post-receive」鉤子中運行此代碼時,重置似乎工作正常;克隆的存儲庫回到沒有大文件的狀態。然而,垃圾收集似乎並沒有奏效。 .git的大小仍然很大。另一方面,如果我在這一點上從命令行手動運行「git reflog」和「git gc」,它會正確刪除巨大文件的痕跡,並將.git的大小恢復爲可管理的大小。

在「post-receive」而不是在命令提示符下運行垃圾收集時可能會有不同行爲的任何想法?

回答

1

Git積極的垃圾收集可能不會做你期待的。 Linus在這裏發佈了關於這個。但是,它也被涵蓋在其他職位:

+0

謝謝,我會嘗試重新包裝。但我的主要觀點是關於在post-receive中運行上述代碼之間的結果差異,而不是之後在命令提示符下手動輸入它。我不明白爲什麼會有所作爲。 –

0

好吧,我覺得我設法去的這條底線。它實際上與收到後沒有任何關係,或者沒有。

更多關於引發此問題的問題。我有一個倉庫,稱之爲「回購」。最後一次提交到這個倉庫是一個巨大的文件,稱它爲「BigFatFile.bin」這是4 MB的大小。這個文件不應該在版本庫中。所以我試圖解決這個問題是這樣的:

  1. 克隆存儲庫。
  2. 執行git reset --hard刪除最後一次提交。

這些步驟設法從克隆的存儲庫中刪除「BigFatFile.bin」。但是,這種推送的效果仍然可見,因爲.git目錄仍然很大:4MB的「BigFatFile.bin」仍然反映在目錄中.git/objects/pack

此時,我可以嘗試各種清理命令試圖擺脫「BigFatFile.bin」的效果:

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin 
git reflog expire --expire=now --all 
git repack -a -d -f --depth=250 --window=250 
git gc --aggressive --prune=now --force 

這些步驟對的.git大小沒有顯著影響。但是,我發現如果我在git reset --hard之後立即執行git push -f origin master,然後執行清理步驟,那麼.git的大小又回到了「BigFatFile.bin」推送之前的大小。這並不能解決我的問題(因爲雖然克隆的存儲庫恢復原樣,但原始存儲庫的大小仍然臃腫)。但是,它確實回答了我爲什麼垃圾收集(和其他清理措施)沒有效果的問題:在我「推送」我的更改之前,.git必須不僅保留文件的本地內容,還必須保留其原始內容。

所以我原來的問題(爲什麼沒有在本地清理工作)被回答,雖然我仍然不知道真正的問題的答案,這是如何重置遠程存儲庫,以便它不顯示「BigFatFile.txt」的提交效果

+0

我不確定這是一個答案,更多的是用gc的新知識來詳細闡述你的問題。那就是如果你正在尋找答案,這可能構成問題的一部分。 – andygavin