未使用のオブジェクトをgitリポジトリから削除するにはどうすればよいですか?


89

誤って、最新のコミットで巨大なバイナリファイルを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 :-(

13
モデレーターへのリマインダーですが、この質問は100%スーパーユーザーではなくSOに属します。
vonC 2010


ここで述べたように(stackoverflow.com/questions/685319/…)、gcの後に再梱包を試みましたか? たとえば、git-repack -aその後に続きgit-prune-packedます。blog.felipebalbi.com/2007/12/19/を
VonC

2
@Jonas:それをすべて行った後、リポジトリのクローンを作成した場合はどうなりますか?う、あなたはその後、目的の小型化とクローンを取得しますか?
vonC 2010

1
@Jonas:あなたがしたすべてのことをした後(filter-branchgcrepack、...)、いいえ、あなたはどんな悪いが全くコミット表示されません。これは、クリーニングが期待どおりに行われなかったことを示しています。
vonC 2010

回答:


127

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

...さらに面倒なことをせずに、この便利なスクリプト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


同様にstackoverflow.com/questions/1904860/...、再びあなたに+1。
vonC 2013

18
素晴らしい:D答えを複製してより多くのポイントを獲得するという私の邪悪な計画はうまくいきました!! 1;)
サムワトキンス

はい!これは機能しましたが、完全なスクリプトを実行する必要がありました。(configオプションを使用して)gcコマンドのみを実行するだけでは不十分でした。
ダニエル

4
102mから160k ..効果的で破壊的
prusswan 2016年

4
スクリプトをどうもありがとう!ボーナス情報:xargs認識されないオプションが原因で、コマンドはOSXでエラーを生成します。最も簡単な解決方法:自作を経由してのGNU xargsのをインストールbrew install findutilsして置き換えるxargsことでgxargs
qqilihq 2017

26

あなたgit reflog expire --allは間違っています。有効期限(デフォルトは90日)より古いreflogエントリを削除します。を使用しgit reflog expire --all --expire=nowます。

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


18

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

  • git rm --cached path/to/file

2)以下を使用してリポジトリを縮小します。

  • git gc

  • または git gc --aggressive

  • または git prune

または、この質問で提案されている上記の組み合わせ:gitリポジトリのサイズを減らす


10

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

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



6

やあ!

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

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

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

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



4
git filter-branch --index-filter 'git rm --cached --ignore-unmatch Filename' --prune-empty -- --all

Filenameリポジトリから削除したいものに変更することを忘れないでください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.