2014-07-14 35 views
3

假設我有一個Git倉庫,其中包含大量樹(〜60 GiB)和一些歷史記錄,其中舊版本包含許多已刪除的文件。修剪舊的Git無需重新綁定

我現在想刪除舊的歷史,但沒有rebase荷蘭國際集團所有提交剪枝點之後,因爲那樣會需要幾個小時每次提交。

  • 我可以只刪除第一個承諾要移除的對象,並希望git gc刪除所有(現未引用的)舊的?或者這會導致恐慌,因爲缺少物體?

  • 我可以使用git replace更換一次提交我想用一個假除去提交和然後呼叫git gc

  • 是否有其他的方法來刪除我的舊提交到位?

+0

我認爲任何種類的歷史重寫都必須涉及在修剪點之後重寫所有內容,除非每個提交的sha ID實際上並不基於其父項的數據。您可以通過'git filter-branch'或BFG Repo Cleaner更有效地進行操作。 –

+0

每個提交的SHA-1 ID * *都是基於其父提交的數據設計的。您必須重新分配:您的剪枝點中的每個提交都需要具有全新的ID,因爲它基於不同的先前提交ID。 –

回答

2

沒有基礎重建的所有提交剪枝點之後,因爲那樣會需要幾個小時每次提交。

這就是graft point是(在特定情況下比git replace更好,因爲我detail here

文件.git/info/grafts與提交ID只有一條線,說,承諾不具有家長。
保留最近100次的提交,使用git rev-parse

git rev-parse HEAD~100 > .git/info/grafts 

然後:

git filter-branch -- --all 

最後:

rm -Rf .git/refs/original 

然後你就可以修剪休息:

git reflog expire --expire=now --all 
git gc --prune=now 
git gc --aggressive --prune=now 
git repack -Ad  # kills in-pack garbage 
git prune   # kills loose garbage 
+0

但移植物不會被推/拉,對吧?聽起來不錯,不必創建一個空的替換提交。我猜測沒有辦法做到這一點,以便替換可以使用推/拉轉移... – cfstras

+0

@cfstras不,移植是純粹的本地。因此需要'git filter-branch',將其修改集成到回購歷史中。一旦完成,您可以推送更改後的歷史記錄。 (一個'push - force',因爲歷史被重寫了,所以確保你是唯一一個處理這個repo的人,或者確保你的同事知道這個改變) – VonC

+0

啊,這是有道理的。我猜'git filter-branch'在這種情況下只會重新處理提交對象(更改父代SHA),因此幾乎可以即時運行? – cfstras