33

いくつかの非常に大きなバイナリを含む git リポジトリがあります。それらはもう必要ありません。以前のコミットからファイルをチェックアウトできるかどうかは気にしません。したがって、レポのサイズを減らすために、履歴からバイナリを完全に削除したいと思います。

ウェブ検索の後、私の最良の(唯一の?)オプションは次を使用することであると結論付けましたgit-filter-branch

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' HEAD

これまでのところ、これは良いアプローチのように思えますか?

答えが「はい」であると仮定すると、対処すべき別の問題があります。git マニュアルには次の警告があります。

警告!書き換えられた履歴は、すべてのオブジェクトのオブジェクト名が異なり、元の分岐に収束しません。元のブランチの上に書き換えられたブランチを簡単にプッシュして配布することはできません。完全な意味がわからない場合は、このコマンドを使用しないでください。問題を解決するために単純な単一のコミットで十分な場合は、とにかく使用しないでください。(公開された履歴の書き換えに関する詳細については、git-rebase(1) の「RECOVERING FROM UPSTREAM REBASE」セクションを参照してください。)

サーバーにリモートリポジトリがあります。各開発者は、それに対してプッシュおよびプルします。上記の警告 (およびその仕組みに関する私の理解) に基づくと、ローカル コピーで実行して変更をプッシュするgit-filter-branchことはできないと思います。git-filter-branch

そのため、暫定的に次の手順を実行する予定です。

  1. すべての開発者に、コミット、プッシュ、および作業を少し停止するように伝えます。
  2. サーバーにログインし、中央リポジトリでフィルターを実行します。
  3. 全員に古いコピーを削除してもらい、サーバーから再度複製してもらいます。

これは正しいと思いますか?これが最善の解決策ですか?

4

4 に答える 4

19

はい、あなたのソリューションは機能します。別のオプションもあります。中央リポジトリでこれを行う代わりに、クローンでフィルターを実行してから、 でプッシュバックしgit push --force --allます。これにより、サーバーはリポジトリから新しいブランチを受け入れるようになります。これはステップ 2 のみを置き換えます。他の手順は同じです。

開発者が Git に精通している場合、古いコピーを削除する必要はないかもしれません。たとえば、新しいリモートをフェッチし、トピック ブランチを適切にリベースできます。

于 2010-12-14T20:55:49.460 に答える
11

あなたの計画は良いです(ただし、中央サーバーではなく、リポジトリの裸のクローンでフィルタリングを実行する方が良いでしょう)、代わりに私のBFG Repo-Cleanergit-filter-branchを使用する必要があります。特にGit リポジトリから大きなファイルを削除する場合。git-filter-branch

Java jar (Java 6 以上が必要) をダウンロードして、次のコマンドを実行します。

$ java -jar bfg.jar  --strip-blobs-bigger-than 1MB  my-repo.git

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

$ git gc --prune=now --aggressive

BFG は通常、実行よりも 10 ~ 50 倍高速でgit-filter-branchあり、オプションは次の 2 つの一般的なユースケースに合わせて調整されています。

  • 非常に大きなファイルを削除する
  • パスワード、資格情報、その他の個人データの削除
于 2013-02-23T17:58:04.443 に答える
5

開発者に再クローンを作成させない場合、開発者は大きなファイルをドラッグして戻すことができる可能性があります。たとえば、開発者が新しい履歴に注意深く接続すると、作成git mergeしたローカルプロジェクトブランチから発生します。リベースされていない場合、マージコミットの親には、で消去した履歴全体を最終的に指すプロジェクトブランチが含まれますgit filter-branch

于 2010-12-14T21:01:21.580 に答える
3

あなたのソリューションは完全ではありません。--tag-name-filter cat大きなファイルを含むタグも変更されるように、ブランチをフィルター処理する引数として含める必要があります。コミットは複数のブランチにある可能性があるため、HEAD だけでなくすべての参照も変更する必要があります。

ここにいくつかのより良いコードがあります:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch big_1.zip big_2.zip etc.zip' --tag-name-filter cat -- --all

Github には優れたガイドがあります: https://help.github.com/articles/remove-sensitive-data

于 2013-07-16T21:43:59.300 に答える