(解決済み、質問本文の下部を参照)
これを長い間探していましたが、私が今まで持っているものは次のとおりです。
ほぼ同じ方法ですが、両方ともオブジェクトをパックファイルに残します...スタックします。
試したこと:
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にリセットしたくないです:(
解決策:これは、ファイルを削除する最短の方法です。
refs/remotes/Origin/master
行。リモートリポジトリの場合は削除します。そうしないと、gitはこれらのファイルを削除しません。git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5
-最大のファイルを確認するgit rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98
-それらのファイルが何であるかを確認するgit filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names'
-すべてのリビジョンからファイルを削除しますrm -rf .git/refs/original/
-gitのバックアップを削除しますgit reflog expire --all --expire='0 days'
-すべてのルーズオブジェクトを期限切れにするgit fsck --full --unreachable
-緩いオブジェクトがあるかどうかを確認しますgit repack -A -d
-再梱包git Prune
-これらのオブジェクトを最終的に削除しますリポジトリデータにアクセスせずに確実に言うことはできませんが、おそらくgit filter-branch
を実行する前からの古いコミットを参照している1つ以上のパックされた参照があると思います。これにより、reflogの有効期限が切れて元の(アンパックされた)refが削除されたにもかかわらず、git fsck --full --unreachable
が大きなblobを到達不能オブジェクトと呼ばない理由が説明されます。
私がやることは次のとおりです(git filter-branch
およびgit gc
が実行された後):
1)元の参照がなくなっていることを確認してください:
rm -rf .git/refs/original
2)すべてのreflogエントリを期限切れにします:
git reflog expire --all --expire='0 days'
)古いパックされた参照の確認
使用するパックrefの数によっては、これは難しい場合があります。これを自動化するGitコマンドは知らないので、手動でこれを行う必要があると思います。 .git/packed-refs
のバックアップを作成します。次に.git/packed-refs
を編集します。古い参照を確認します(特に、.git/refs/original
の参照をパックしているかどうかを確認します)。そこにある必要のない古いものを見つけたら、それらを削除します(その参照の行を削除します)。
packed-refs
ファイルのクリーンアップが完了したら、git fsck
が到達不能オブジェクトに気付いたかどうかを確認します。
git fsck --full --unreachable
それが機能し、git fsck
が大きなBLOBに到達不能として報告するようになったら、次のステップに進むことができます。
4)パックされたアーカイブを再パックします
git repack -A -d
これにより、到達不能オブジェクトがアンパックされ、stayアンパックされることが保証されます。
5)ルーズ(到達不能)オブジェクトのプルーニング
git Prune
そして、それはそれを行う必要があります。 Gitには、パックされた参照を管理するためのより良い方法が必要です。たぶん、私が知らないより良い方法があるでしょう。より良い方法がない場合、packed-refs
ファイルを手動で編集することが唯一の方法です。
BFG Repo-Cleaner を使用することをお勧めします。これは、Git履歴からファイルを書き換えるために特別に設計されたgit-filter-branch
のよりシンプルで高速な代替手段です。ここであなたの生活を楽にする一つの方法は、デフォルトでall参照(すべてのタグ、ブランチ、refs/remotes/Origin/masterなど)を実際に処理することですが、それも 10-50x 速くなりました。
ここでこれらの手順を注意深く実行する必要があります: http://rtyley.github.com/bfg-repo-cleaner/#usage -しかし、コアビットはこれだけです: BFGのjar (Java 6以上が必要))で、次のコマンドを実行します。
$ Java -jar bfg.jar --delete-files file_name my-repo.git
file_name
(latest commitにない)という名前のファイルは、リポジトリの履歴からtotally removedになります。その後、git gc
を使用して、デッドデータを一掃できます。
$ git gc --Prune=now --aggressive
BFGは一般にgit-filter-branch
よりもはるかに簡単に使用できます-オプションは次の2つの一般的なユースケースに合わせて調整されます。
完全な開示:私はBFGリポジトリクリーナーの作成者です。
上記は実際には役に立たなかったため、フォルダー全体を削除することに関してこれが非常に役立つことがわかりました: 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
私は歴史の中で大きなファイルを取り除こうとしていましたが、上記の答えはうまくいきました。ポイントは、タグがあると機能しないことです。大きなファイルを含むコミットがタグから到達可能な場合、次のようにfilter-branchesコマンドを調整する必要があります。
git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
ファイルがリビジョンに存在しない場合、上記は失敗します。その場合、「-ignore-unmatch」スイッチで修正されます。
git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD
次に、すべてのゆるいオブジェクトを再配置から取得するには:
git gc --Prune='0 days ago'
git gc
の後のgitリポジトリサイズがまだ大きい理由はさまざまです。なぜなら、それは すべての緩いオブジェクトを削除しない であるためです。
これらの理由については、「 gitリポジトリサイズを小さくする 」で詳しく説明します。
しかし、あなたのケースでテストする1つのトリックは、 clone「クリーンな」Gitリポジトリ で、クローンに適切なサイズ。
( '"cleaned"リポジトリ'は、filter-branch
を適用した後、gc
とPrune
を適用したリポジトリです)
これは、Git Extrasのgit obliterate
コマンドでカバーする必要があります( https://github.com/visionmedia/git-extras )。
git obliterate <filename>
私は同じ問題を抱えていて、誤ってコミットしたファイルを取り除く方法を段階的に説明する素晴らしい tutorial をgithubで見つけました。
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