2

私が従業員である有名なドイツのソフトウェア会社「Apfel」によって作成された、「Hammerstein」と呼ばれる、まだ公開されていないソフトウェア製品の巨大なレポがあるとします。

ある日、「アプフェル」はハマースタイン部門をスピンアウトし、それをさらに有名な会社「オラキュロ」に売却します。オラクロは「ハマースタイン」を国家の誇りとして「レイネタ」に改名し、オープンソースにすることを決定します。

契約では、リポジトリ内の「Hammerstein」と「Apfel」へのすべての参照を「Oráculo」と「Reineta」に置き換えることが義務付けられています。

すべてのファイル名、すべてのコミット メッセージ、すべてを置き換える必要があります。

たとえば、次のようになります。

  1. src/core/ApfelCore/main.cppなる必要がありsrc/core/OraculoCore/main.cppます。

  2. "Add support for Apfel Groupware Server"なる必要があるというコミットメッセージ"Add support for Oraculo Groupware Server"

  3. 文字列ApfelServerInstance* local_apfel#define REINETAおよびは、、、などUrl("http://apfel.de")になる必要があります。OraculoServerInstance* local_oraculo#define HAMMERSTEIN

これは、もう存在しないファイルにも当てはまりますHEAD

最小限の手動介入でそれを達成するための最も簡単で最も痛みのない方法は何ですか(潜在的に多数のリポジトリ/アセットにバッチで適用できるようにするため)?

  1. BFG--delete-fileは文字列を置き換えることができますが、 ではなくオプションしかないようです--rename-file。さらに、引数としてパターンを取りません。
  2. このアプローチHEADは、歴史全体に対してのみ有効であり、有効ではないようです。私はそれを使って運がなかった--tree-filter
4

2 に答える 2

4

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

質問で言うように、BFG はファイル コンテンツを--replace-textフラグで置き換えることをサポートしていますが、このフラグはファイルとコミット メッセージには適用されません。では、BFG の--replace-text操作をそれらにも拡張するには、コードベースにどのような変更を加える必要があるでしょうか?

Cleaner[V]これは、いくつかの新しい実装をフックすることに帰着します。ここVで、 はクリーンアップしたいもののタイプ (コミット メッセージ、ディレクトリ リスト) であり、には古いダーティな からCleanerクリーンな新しい を生成するだけの仕事があります。実際のテキスト変更を実行するには、ファイル コンテンツの変更に使用したのと同じテキスト置換関数を再利用できます。VV

ファイル名

Cleaner[Seq[Tree.Entry]]ツリー」は Git がフォルダー (「ファイル ツリー」) と呼ぶものFileNameですTree.Entry

メッセージをコミットする

を使用してください- 繰り返しますが、フィールドCleaner[CommitNode]のテキストを置き換えるだけです- CommitMessageObjectIdsUpdaterを参照して、あなたがしようとしていることの非常に近い例を確認してください。そこにいる間に、必要に応じて作成者とコミッターのメールアドレスを使って何かをすることができます (例えば、purgeだと思います)。message...@apfel.com

スピード

彼の回答で@VonCが述べたように、filter-branch これらの両方の置換(ファイル名とコミットメッセージ)を実行できますが、--msg-filterフラグはコミットメッセージの更新をかなり迅速に実行する必要がありますが、次のような大規模なコードベース内のファイルの名前を変更するには、かなり遅くfilter-branchなると思いますあなたの。まさにこの種の操作用に最適化された BFG は、数倍高速になります。

BFG はhttps://www.bountysource.com/teams/bfg-repo-cleanerで寄付を受け付けています。この機能の開発をサポートしたい場合、または BFG が問題の解決に役立つことがわかった場合は、違いを生み出すことができる場所。

于 2015-09-21T07:21:44.473 に答える
2

単一の簡単なステップで?

単一ではなく、それほど単純ではありませんが、可能です:


コミットメッセージを更新するには、次を使用する必要がありthe --msg-filterますgit filter-branch

git filter-branch -f --msg-filter 'sed "s/Apfel/Oraculo/"' -- --all

すべてのブランチのすべてのコミット--allをフィルタリングするために、 に注意してください。 別のケースに対処するために、そのコマンドを数回繰り返す必要がある場合があります。


--tree-filter を使用せずにファイルを移動するには、この回答(およびこの記事) を参照し、新しいパスを構築するためにそれを適応させることができます。

git filter-branch --index-filter 'git ls-files -s | \
  sed "s,/ApfelCore/,/OraculoCore/," | \
  GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && \
  mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' \
-- --all

前述のように、BFGはすべての文字列を置き換えることができます。「 git履歴のファイルからテキストを置き換える方法は?」を参照してください。

java -jar bfg.jar --replace-text replacements.txt my-repo.git

ファイルには、replacements.txt実行するすべての置換が次のような形式で含まれている必要があります (1 行に 1 つのエントリ)。

Apfel==>Oraculo
apfel==>oraculo
REINETA==>HAMMERSTEIN
于 2015-09-20T10:55:36.137 に答える