2010-01-29 125 views
70

(解決了,看到問題體的底部)
尋找這個現在很長一段時間,我有什麼到現在是:刪除文件(歷史)

幾乎相同的方法,但他們都留在包文件中的對象...卡住了。
我的嘗試:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name' 
rm -Rf .git/refs/original 
rm -Rf .git/logs/ 
git gc 

還有在包文件,這是我怎麼知道的:

git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3 

這:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD 
rm -rf .git/refs/original/ && git reflog expire --all && git gc --aggressive --prune 

同...

試過git clone訣竅,它刪除了一些文件(〜其中3000),但最大的文件仍然存在...

我有一些在存儲庫中的大型遺留文件,〜200M,我真的不希望他們在那裏......而且我不想庫重置爲0 :(

SOLUTION: 這是擺脫了文件的最短途徑:

  1. 檢查的.git /填充裁判 - 我的問題是,我有沒有refs/remotes/origin/master線對於遠程倉庫,刪除它,否則git將不會刪除這些文件
  2. (o ptional)git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - 檢查最大文件
  3. (可選)git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 - 要檢查那些是什麼文件
  4. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' - 從所有版本
  5. rm -rf .git/refs/original/刪除文件 - 刪除Git的備份
  6. git reflog expire --all --expire='0 days' - 到期的所有鬆動物體
  7. git fsck --full --unreachable - 檢查是否有任何鬆動的對象
  8. git repack -A -d - 重新包裝
  9. git prune - 終於去掉這些對象
+5

Soooo,你的問題是......? – zneak 2010-01-29 19:31:05

+0

可能的重複項:http://stackoverflow.com/questions/2100907/how-to-purge-a-huge-file-from-commits-history-in-git/2158271 http://stackoverflow.com/questions/872565/how-do-i-remove-sensitive-files-from-gits-history – 2010-01-29 20:58:14

+0

zneak - 我的問題在標題中。 gbacon - 試過這些,這些文件仍然保留在包文件中... – Devenv 2010-01-29 22:52:16

回答

59

我不能肯定地說沒有訪問您的庫數據,但我相信有在運行git filter-branch之前,可能還有一個或多個打包引用依然引用舊的提交。這可以解釋爲什麼git fsck --full --unreachable不會將大blob稱爲無法訪問的對象,即使您已經過期了reflog並刪除了原始(未打包)的引用。

這是我會怎麼做(git filter-branchgit gc已經完成後):

1)確認原裁判都不見了:

rm -rf .git/refs/original

2)過期的所有引用日誌條目:

git reflog expire --all --expire='0 days'

3)檢查舊包裝的裁判

這可能會非常棘手,這取決於你有多少打包裁判有。我不知道任何Git命令會自動執行此操作,因此我認爲您必須手動執行此操作。備份.git/packed-refs。現在編輯.git/packed-refs。檢查舊的參考(特別是,看它是否包裝從.git/refs/original任何參考)。如果您發現任何不需要在那裏的舊的,刪除它們(刪除該參考線)。

在完成清理packed-refs文件,看是否git fsck注意到無法訪問的對象:

git fsck --full --unreachable

是否奏效,以及git fsck現在報告你的大斑點爲不可達,你可以移動到下一步。

4)重新包裝打包存檔(S)

git repack -A -d

這將確保不可達的對象得到解壓和住宿解壓。

5)修剪鬆動(不可達)對象

git prune

而且應該這樣做。 Git真的應該有更好的方式來管理打包裁判。也許有一種我不知道的更好的方式。如果沒有更好的方法,手動編輯packed-refs文件可能是唯一的出路。

+1

Yey! !我愛你 ! 問題出現在packed-refs文件中,從某些服務器上備份起來的時候有refs/remotes/origin/master ...一旦我刪除它,它就開始消失......謝謝! (使用完整的解決方案更新問題主體) – Devenv 2010-02-02 00:43:19

+0

呵呵,關於packed-refs的提示非常有幫助! – 2014-12-12 11:20:48

2

參見:How do I remove sensitive files from git’s history

如果文件不以轉存在上面會失敗。在這種情況下,「 - 忽略的不匹配」開關將修復它:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD 

然後,讓所有鬆散物出repostiry的:

git gc --prune='0 days ago' 
+0

是的,試過這個,仍然有包中的文件,並且尺寸沒有變化太多... – Devenv 2010-01-29 22:53:48

+0

我只是做了一個混帳沙箱,並嘗試過它。這裏也不好。讓我們看看我能弄清楚什麼。 – 2010-01-30 01:07:17

+0

明白了。請參閱編輯版本。 – 2010-01-30 02:01:59

1

您有多種原因的仍大的git回購股票的大小在git gc之後,因爲它是does not remove all loose objects

我詳細的「reduce the git repository size

但一招這些原因在你的情況,以測試將clone your "cleaned" Git repo,看看無性系都具有適當的大小。

(「‘乾淨’回購」作爲一個地方你做套用filter-branch,然後gcprune

+0

是的,它已經測試過了,現在再測試一次,它減少了2K的存儲庫:)並且這些文件仍然存在...... – Devenv 2010-02-01 10:06:09

+0

奇怪的是'git count-objects -v - > count:0,size:0,in-pack :10021,packs:1,size-pack:244547,prune-packable:0,garbage:0' 但是:'git clone test1 test2 - >檢出文件:100%(8509/8509),done' – Devenv 2010-02-01 10:11:56

4

我試圖擺脫歷史上的一個大文件,上面的答案奏效,直到一點。重點是:如果你有標籤,他們不會工作。如果提交包含大文件是從一個標籤到達,那麼你就需要調整濾波器分支命令正是如此:

git filter-branch --tag-name-filter cat \ 
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \ 
--all --tags 
0

我有同樣的問題,我發現在GitHub上有很大tutorial通過解釋一步步驟如何擺脫您意外犯下的文件。

下面是Cupcake建議的程序的小結。

如果你有一個名爲file_to_remove從歷史記錄中刪除文件:

cd path_to_parent_dir 

git filter-branch --force --index-filter \ 
    'git rm --cached --ignore-unmatch file_to_remove' \ 
    --prune-empty --tag-name-filter cat -- --all 
+0

鏈接只有堆棧溢出非常沮喪的回答,因爲如果鏈接在未來中斷,那麼答案變得毫無用處。請考慮總結答案中鏈接中包含的相關信息。 – 2014-04-04 00:05:06

+0

我更新了我的答案。感謝您的建議。 – 2014-04-04 09:58:35

6

我發現這是與問候非常有助於消除整個文件夾的上面並沒有真正幫助我:https://help.github.com/articles/remove-sensitive-data

我使用:

git filter-branch -f --force \ 
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \ 
--prune-empty --tag-name-filter cat -- --all 

rm -rf .git/refs/original/ 
git reflog expire --expire=now --all 
git gc --prune=now 
git gc --aggressive --prune=now 
7

我建議使用BFG Repo-Cleaner,更簡單,更快速的替代git-filter-branch專門針對提交歷史重寫文件而設計的。其中一種讓你的生活更輕鬆的方式是它實際上默認處理所有引用(所有標籤,分支,像refs/remotes/origin/master等等),但它也快於10-50x

您應仔細按照這些步驟在這裏:http://rtyley.github.com/bfg-repo-cleaner/#usage - 但核心的一點就是這一點:下載BFG's jar(需要Java 6或以上),並運行此命令:

$ java -jar bfg.jar --delete-files file_name my-repo.git 

任何命名file_name文件(即是不是在您的最新提交)將從您的存儲庫的歷史將完全刪除。然後,您可以使用git gc清理掉死數據:

$ git gc --prune=now --aggressive 

的BFG一般是簡單得多比git-filter-branch使用 - 選項都是圍繞這兩個常見的用例定製:

  • 刪除瘋狂大文件
  • 刪除密碼,證書 &其他私人數據

完全披露:我是BFG Repo-Cleaner的作者。

+0

這是否也推送後從遠程倉庫清理私人數據? – 2013-07-23 06:20:10

+0

@ThomasLauria yup,同樣的清理文件在推送時被推送到遠程回購 - http://rtyley.github.io/bfg-repo-cleaner/#usage上的說明應該覆蓋它。如果您可以控制遠程回購,那麼您也可以在推送後運行「git gc --prune = now --aggressive」以確保立即從中刪除死對象。 – 2013-07-23 08:11:53