906

誤って DVD-rip を Web サイトのプロジェクトに落としてしまい、うっかりgit commit -a -m .... 次回、編集を行い、ビデオ ファイルを削除し、すべてをコミットしましたが、圧縮ファイルは履歴のリポジトリに残っています。

それらのコミットからブランチを開始し、あるブランチを別のブランチにリベースできることを知っています。しかし、大きなファイルが履歴に表示されず、ガベージ コレクション手順でクリーンアップされるように、2 つのコミットをマージするにはどうすればよいですか?

4

21 に答える 21

732

Git 履歴から不要なファイルを削除するために特別に設計された、よりシンプルで高速な代替手段であるBFG Repo-Cleanerを使用します。git-filter-branch

慎重に使用方法に従ってください。コア部分は次のとおりです。

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

サイズが 100 MB を超える (最新のコミットにない) ファイルは、Git リポジトリの履歴から削除されます。git gcその後、デッド データを消去するために使用できます。

$ git gc --prune=now --aggressive

通常、BFG は実行中よりも少なくとも10 ~ 50 倍git-filter-branch高速であり、一般的に使いやすいです。

完全な開示: 私は BFG Repo-Cleaner の作成者です。

于 2013-07-26T20:15:38.153 に答える
648
于 2010-01-28T21:55:32.550 に答える
47

git filter-branch よりも 100 倍高速でシンプル

このスレッドには非常に優れた回答がありますが、それらの多くは時代遅れです。使用git-filter-branchが難しく、大きなリポジトリでは非常に遅いため、使用は推奨されなくなりました。

git-filter-repoはるかに高速で使いやすいです。

git-filter-repoは Python スクリプトで、github: https://github.com/newren/git-filter-repoで入手できます。インストールすると、通常の git コマンドのように見え、git filter-repo.

必要なファイルは 1 つだけです: Python3 スクリプト git-filter-repo. PATH 変数に含まれるパスにコピーします。Windows では、スクリプトの最初の行を変更する必要がある場合があります (INSTALL.md を参照)。システムに Python3 をインストールする必要がありますが、これは大した問題ではありません。

最初に実行できます

git filter-repo --analyze

これは、次に何をすべきかを判断するのに役立ちます。

DVD-rip ファイルはどこからでも削除できます。

git filter-repo --invert-paths --path-match DVD-rip
 

Filter-repo は本当に高速です。私のコンピューターでは、filter-branch で約 9 時間かかったタスクが、filter-repo で 4 分で完了しました。filter-repo を使用すると、さらに多くの便利なことができます。これについては、ドキュメントを参照してください。

警告:これはリポジトリのコピーに対して行ってください。filter-repo の多くのアクションは元に戻すことができません。filter-repo は、変更されたすべてのコミット (もちろん) とそのすべての子孫のコミット ハッシュを最後のコミットまで変更します!

于 2020-05-04T22:56:00.410 に答える
42

私の場合、これらのコマンドは機能しました:

git filter-branch --force --index-filter 'git rm --cached -r --ignore-unmatch oops.iso' --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

上記のバージョンとは少し異なります。

これを github/bitbucket にプッシュする必要がある場合 (bitbucket でのみテストしました):

# WARNING!!!
# this will rewrite completely your bitbucket refs
# will delete all branches that you didn't have in your local

git push --all --prune --force

# Once you pushed, all your teammates need to clone repository again
# git pull will not work
于 2013-06-14T02:35:36.637 に答える
12

私は自分のサイトの巨大な *.jpa バックアップを誤って保存していた bitbucket アカウントでこれに遭遇しました。

git filter-branch --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch MY-BIG-DIRECTORY-OR-FILE' --tag-name-filter cat -- --all

問題のフォルダーに置き換えて、履歴 (タグを含むMY-BIG-DIRECTORY)を完全に書き換えます。

ソース: https://web.archive.org/web/20170727144429/http://naleid.com:80/blog/2012/01/17/finding-and-purging-big-files-from-git-history/

于 2014-08-31T19:33:54.787 に答える
10

このコマンドは非常に破壊的である可能性があることに注意してください。より多くの人がリポジトリで作業している場合、全員が新しいツリーをプルする必要があります。サイズを小さくすることが目的でない場合、真ん中の 3 つのコマンドは必要ありません。フィルター ブランチは、削除されたファイルのバックアップを作成し、そこに長期間留まることができるためです。

$ git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch YOURFILENAME" HEAD
$ rm -rf .git/refs/original/ 
$ git reflog expire --all 
$ git gc --aggressive --prune
$ git push origin master --force
于 2012-06-14T11:53:46.350 に答える
9

git filter-branch --tree-filter 'rm -f path/to/file' HEADここで 説明したのと同じ問題に遭遇しましたが、私はこの提案に従って解決しました。

pro-git book には、履歴の書き換えに関する章全体があります - filter-branch/Removing a File from Every Commitセクションを見てください。

于 2012-10-25T12:24:36.620 に答える
8

ツリー全体を調べるのではなく、コミットが最近のものであることがわかっている場合は、次の手順を実行します。 git filter-branch --tree-filter 'rm LARGE_FILE.zip' HEAD~10..HEAD

于 2016-01-01T06:21:33.863 に答える
-1
git reset --soft HEAD~1

変更は保持されますが、コミットが削除されてから、それらの変更を再コミットできます。

于 2021-12-23T11:23:37.553 に答える