web-dev-qa-db-ja.com

Gitリポジトリから未使用のオブジェクトを削除する方法は?

Gitリポジトリへの最新のコミットで巨大なバイナリファイルを誤って追加、コミット、プッシュしました。

.gitディレクトリが再び正常なサイズに縮小するように、Gitにそのコミット用に作成されたオブジェクトを削除させるにはどうすればよいですか?

編集:ご回答いただきありがとうございます。いくつかの解決策を試しました。動作しませんでした。たとえば、GitHubのファイルは履歴からファイルを削除しましたが、.gitディレクトリのサイズは減少していません。

$ BADFILES=$(find test_data -type f -exec echo -n "'{}' " \;)

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $BADFILES" HEAD
Rewrite 14ed3f41474f0a2f624a440e5a106c2768edb67b (66/66)
rm 'test_data/images/001.jpg'
[...snip...]
rm 'test_data/images/281.jpg'
Ref 'refs/heads/master' was rewritten

$ git log -p # looks Nice

$ rm -rf .git/refs/original/
$ git reflog expire --all
$ git gc --aggressive --Prune
Counting objects: 625, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (598/598), done.
Writing objects: 100% (625/625), done.
Total 625 (delta 351), reused 0 (delta 0)

$ du -hs .git
174M    .git
$ # still 175 MB :-(
76
Jonas H.

私は他の場所でこれに答えました、そして私はそれを誇りに思っているので、ここにコピーします!

...さらに苦労せずに、この便利なスクリプトgit-gc-allを提示して、余分な構成変数が見つかるまですべてのgitガベージを削除することを保証できますか。

git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 \
  -c gc.rerereresolved=0 -c gc.rerereunresolved=0 \
  -c gc.pruneExpire=now gc "$@"

--aggressiveオプションが役立つ場合があります。

注:これにより、参照されていないものがすべて削除されるため、後でそれらの一部を保持することを決定した場合、私に泣かないでください!

また、これらのようなものを最初に実行する必要があるかもしれません、ああ、Gitは複雑です!!

git remote rm Origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ |
  xargs -n1 --no-run-if-empty git update-ref -d

ここにすべてをスクリプトに入れます:

http://sam.nipl.net/b/git-gc-all-ferocious

115
Sam Watkins

きみの git reflog expire --all 間違っています。有効期限(デフォルトは90日)より古いreflogエントリを削除します。つかいます git reflog expire --all --expire=now

私の答え 同様の質問に対して、リポジトリから未使用のオブジェクトを実際にスクラブする問題を扱います。

25
Josh Lee

1)gitリポジトリからファイルを削除します(ファイルシステムではなく):

  • git rm --cached path/to/file

2)次を使用してレポを縮小します:

  • git gc

  • またはgit gc --aggressive

  • またはgit Prune

またはこの質問で提案されている上記の組み合わせ: Reduce git repository size

17
Jamie

機密データの削除 に関するこのガイドは、同じ方法を使用して適用できます。履歴を書き換えて、存在していたすべてのリビジョンからそのファイルを削除します。これは破壊的であり、他のチェックアウトとレポジトリの競合を引き起こすため、最初に共同編集者に警告してください。

リポジトリで他の人がバイナリを利用できるようにしたい場合、望むことをする本当の方法はありません。それはほとんどまたはまったくありません。

10
Daenyth

私にとっての鍵は、git repack -A -d -f その後 git gc私が持っていた単一のgitパックのサイズを減らすため。

7

やあ!

Gitは、リポジトリを複製するときに実際に必要なオブジェクトのみを受け取ります(正しく理解している場合)

したがって、誤って追加されたファイルを削除して最後のコミットを修正し、変更をリモートリポジトリにプッシュできます(サーバー上の古いコミットも上書きする-fオプションを使用)

次に、そのレポの新しいクローンを作成すると、その.gitディレクトリは、大きなファイルがコミットされる前と同じくらい小さくなります。

必要に応じて、サーバーから不要なファイルも削除する場合は、サーバー上のリポジトリを削除し、新しく複製されたコピー(完全な履歴がある)をプッシュできます。

6
u-foka

Pro Gitブックの「オブジェクトの削除」を参照してください。

http://git-scm.com/book/en/Git-Internals-Maintenance-and-Data-Recovery#Removing-Objects

更新:BFGリポジトリクリーナーも参照してください: http://rtyley.github.io/bfg-repo-cleaner/

4
Czarek Tomczak
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --Prune-empty -- --all

リポジトリから削除するもののFilenameを忘れずに変更してください。

4
Martin