3

リポジトリが大きくなりすぎて使用できなくなりました。基本的に、私のリポジトリは 2GB を超えており、複製に時間がかかりすぎます。縮小したいのですが、特定の古いバージョンに戻すことはできます... 縮小には履歴の書き換えが含まれるので、それで問題ありません。クローンを持っている人は、新しいレポクローンの新しいブランチの上にファイルをリベース/チェリーピック/コピーする必要があります。

  • このリポジトリにバイナリ ファイルがありますが、そこに必要です (ソフトウェアを実行するための必須のリソースと考えてください)。そのため、過去のコミットに戻すときに必要になる可能性があるため、フィルターブランチまたはBFGを使用して大きなバイナリ ファイルを削除することはできません。
  • 以前の古い/既にマージされたブランチ (例: フィーチャー ブランチ) は気にしませんが、いくつかの特定のコミット (過去のリリース ブランチの例のヘッド) は気にします。
  • (~多数~) 非常に古いコミットを変更するので、(基本的な rebase/cherrypick で発生する可能性があるように) マージの競合を適切に解決する方法がわかりません。そのため、競合が発生しない解決策を探しています。自動的に解決できる競合のみを生成します。
  • 現在のすべてのブランチを保持したいので、クローンで作業を行っている人は、それらの変更をリベース/コピーできます。
  • 古いレポの履歴と一致するように、新しいコミット間に関連する履歴が必要です (コミットが押しつぶされたかのように)。現在のブランチの履歴は、これらの古い押しつぶされたコミットの 1 つから始まります。

私はそれを不要な古いリポジトリ履歴のスカッシュと考えています。私の場合の可能なプロセスとしてこれまでに思いついたのは(いくつかの手順を見逃しており、これが私が思うことを行うかどうかまだ確信が持てません)は次のとおりです。

  • 既存のリポジトリのミラーをクローンします。
  • 保持したい古いコミットから孤立したブランチを作成します。これにより、必要なすべてのファイルを含む、親のない押しつぶされたコミットが作成されます。
  • どういうわけかそれらをリンクして古いレポ履歴を再作成します=>どのように? マージ/リベース/リセット+コミットの孤児?
  • 各現在のブランチのコミット リストを (間隔を使用して) チェリーピックし、それらを最初の発散コミットの親を押しつぶした最新のコミットに適用する => チェリー ピックされたコミット間隔を適用するコミットを自動的に見つける方法は? それは競合なしで機能しますか?
  • タグを新しいツリーに移動します。前のツリーを削除します。gitガベージコレクト。

これは競合なしで実行可能/実行可能ですか? これはどのような場合でも機能しますか (git commit ツリーはかなり複雑になる可能性があります)? 安全かつ自動的に履歴をつぶすためのより良い解決策はありますか?

この種のメンテナンス タスクは、長期にわたるプロジェクトで発生するものであるように思われるため、他の大きなプロジェクトで何らかのソリューションが既に使用されていると思います。しかし、このユースケースの古いレポから新しいレポを作成するために、私が気付いていない git init (または別のコマンド) のオプションがあると思いますか?

更新:ここで解決策の始まりを見つけました: https : //wincent.com/wiki/Editing,_amending,_or_squashing_the_root_commit_in_a_Git_repository .

4

3 に答える 3

1

リポジトリの一部だけを複製できます。

git clone --depth depth 

これは浅いクローンと呼ばれます。

これは、大規模なリポジトリを処理するための他の戦略を提供する、少し前の Atlassian ブログの投稿でした。

于 2014-10-24T20:02:12.253 に答える
1

数日間の試行錯誤の後、ここに私が最も良いと思う解決策があります:

1) 新しいルートとして使用するコミットからcheckout --orphan、孤立したブランチを作成するために a を実行し、このバージョンの変更されたファイルをコミットします。

2) 保持したいコミット C ごとに、checkoutCresetを前の新しいコミット B' にコミットし、B' を親として、C' の新しいコミットを作成するためにコミットします。(リンクをくれたforvaidyaに感謝)

3) 次に、既存のブランチを保持した最後のコミットに再リンクする必要があります。古い履歴でそのコミットを見つけます。そこから、それ(またはその親のいずれか)を直接の親として持つすべてのコミットをリストします。次に、新しいものを使用しgit replace --graftて、古い親を新しいコミットに置き換えることができます。

ただし、これのための誰にでもできるスクリプトを考え出すことは非常に便利です...もしそうすることがあれば、ここに投稿します。

警告: 手順 3) は、git 2.X を使用している場合にのみ機能します。1.X git クライアントは、コミット グラフの変更を認識しません。

于 2014-10-26T09:37:37.440 に答える
0

Git の浅いクローンは 1 つの答えですが、浅いクローンではプッシュできません。

squash に関する限り、squash は未公開の履歴でのみ有効です。このリンクは役に立つかもしれませんhttp://www.awanitech.com/git-squash.html

プッシュ後に実行されるスカッシュは、FF プッシュではないため、別のブランチでコミットする必要があります。このようなスカッシュは、リポジトリのサイズには影響しません。

強制プッシュ (履歴の書き換え) を実行する準備ができている場合。次に、フィルター分岐を実行してサイズを縮小できます。

悪いバージョンがまったく異なるブランチにある場合; git バンドルを作成し、それを要約リポジトリとして作成できます。

于 2014-10-25T13:54:24.450 に答える