81

(解決済み、質問本文の下部を参照)
これを長い間探していると、今まで持っていたのは次のとおりです。

ほぼ同じ方法ですが、どちらもオブジェクトをパックファイルに残します...スタックします。
私が試したこと:

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個)が削除されましたが、最大のファイルはまだ残っています...

リポジトリに2億までの大きなレガシーファイルがありますが、それらは本当に必要ありません...そしてリポジトリを0にリセットしたくありません:(

解決策:これは、ファイルを削除するための最短の方法です。

  1. check .git / packed-refs-私の問題はrefs/remotes/origin/master、リモートリポジトリの行があったことでした。それを削除しないと、gitはそれらのファイルを削除しません。
  2. (オプション) 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-最終的にそれらのオブジェクトを削除します
4

8 に答える 8

67

リポジトリデータにアクセスしないとはっきりとは言えませんが、実行する前の古いコミットを参照しているパックされた参照が1つ以上あると思いますgit filter-branchgit fsck --full --unreachableこれは、reflogの有効期限が切れて、元の(解凍された)refを削除した場合でも、大きなblobを到達不能オブジェクトと呼ばない理由を説明します。

これが私がすることです(後でgit filter-branchそしてgit gc行われた):

1)元の参照がなくなっていることを確認します。

rm -rf .git/refs/original

2)すべてのreflogエントリを期限切れにします。

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)パックしたアーカイブを再パックします

git repack -A -d

これにより、到達不能なオブジェクトが確実に解凍され、解凍されたままになります。

5)緩んだ(到達できない)オブジェクトを削除します

git prune

そして、それはそれを行う必要があります。Gitには、パックされた参照を管理するためのより良い方法が本当に必要です。多分私が知らないより良い方法があります。より良い方法がない場合は、ファイルを手動で編集packed-refsすることが唯一の方法である可能性があります。

于 2010-02-01T20:01:13.980 に答える
15

BFG Repo-Cleanerを使用することをお勧めします。これgit-filter-branchは、Git履歴からファイルを書き換えるために特別に設計された、よりシンプルで高速な代替手段です。ここでの作業を楽にする1つの方法は、デフォルトですべての参照(すべてのタグ、ブランチ、refs / remotes / origin / masterなど)を実際に処理することですが、 10〜50倍高速です。

ここで次の手順を慎重に実行する必要があります: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名前が付けられた(最新のコミットに含まれていない)ファイルはすべて、リポジトリの履歴から完全に削除されます。次に、を使用git gcしてデッドデータをクリーンアップできます。

$ git gc --prune=now --aggressive

BFGは、一般的に、よりもはるかに簡単に使用できgit-filter-branchます。オプションは、次の2つの一般的なユースケースに合わせて調整されています。

  • クレイジービッグファイルの削除
  • パスワード、クレデンシャル、その他のプライベートデータの削除

完全な開示:私はBFGレポクリーナーの作者です。

于 2013-04-02T18:00:51.197 に答える
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
于 2013-03-20T14:27:01.183 に答える
5

私は歴史の中で大きなファイルを取り除こうとしていました、そして上記の答えはある程度までうまくいきました。重要なのは、タグがある場合は機能しないということです。大きなファイルを含むコミットがタグから到達可能である場合は、次のようにfilter-branchesコマンドを調整する必要があります。

git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
于 2012-04-19T09:07:13.540 に答える
3

git obliterateこれは、Git Extras(https://github.com/visionmedia/git-extras )のコマンドでカバーする必要があります。

git obliterate <filename>
于 2013-03-25T20:25:49.283 に答える
2

参照:gitの履歴から機密ファイルを削除するにはどうすればよいですか?

ファイルがリビジョンに存在しない場合、上記は失敗します。その場合、「-ignore-unmatch」スイッチで修正されます。

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

次に、すべての緩いオブジェクトを再投稿から除外するには、次のようにします。

git gc --prune='0 days ago'
于 2010-01-29T20:57:12.803 に答える
2

緩んだオブジェクトがすべて削除されるわけgit gcではないため、後もgitリポジトリのサイズが大きいのにはさまざまな理由があります。

これらの理由については、「gitリポジトリのサイズを減らす」で詳しく説明しています。

ただし、この場合にテストする1つのトリックは、「クリーンな」Gitリポジトリのクローンを作成し、クローンのサイズが適切かどうかを確認することです。

('"cleaned" repo'は、を適用したものfilter-branchであり、次にgcprune

于 2010-02-01T05:04:21.150 に答える
1

同じ問題が発生し、誤ってコミットしたファイルを削除する方法を段階的に説明するgithubのすばらしいチュートリアルを見つけました。

カップケーキが提案した手順の簡単な要約を次に示します。

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
于 2013-03-12T12:02:21.327 に答える