0

始める前の簡単なメモ: 「準備」には多くの説明が必要であり、これはプログラミングの問題に関する質問というよりも、設計に関する質問のように思えるかもしれません。実はSVNの分岐とマージについての質問なので、最後まで読んでください。

シナリオ:

かなりの数のプロジェクトを含む大規模な Visual Studio ソリューションがあります。私は SVN を使用しているので、もちろんトランクには私の開発ラインがあります。これは、コア DLL アセンブリ、「メイン」UI ユーザー クライアント、および UI 内で機能を提供するためにコア アセンブリにインターフェイスを実装し、一連のサービスを利用することによって動作する少数の「プラグイン」アセンブリで構成されます。すべてのプラグインに共通の機能を提供するメソッド (永続化ロジック操作、集中型ファイル ストア アーキテクチャのストレージ操作など)

ここに画像の説明を入力

また、時間をかけて作成した外部ユーティリティもあり、プラグインの多くのビジネス ロジックを複製する必要があります。最終的に私の主な質問から気をそらすので、詳細には触れませんが、たとえば、特定のプラグインのデータに関連する集中メンテナンス操作を処理するサーバー上のスケジュールされたサービスを想像してみてください。

私が最初にこのアプリケーションを構築したとき、私は (愚かなことに) 一元化されたサービス層の必要性を予期していなかったので、上に示したように (良くも悪くも) コア アセンブリを設計し、アプリケーションのプレゼンテーション層と緊密に統合しました。 . つまり、プラグインをユーザー インターフェイスに統合するために必要な UI プレゼンテーション ロジックと、プラグインが共通のプラグイン ロジック操作を実行するために必要なビジネス ロジックは、すべて 1 つの「コア」アセンブリの一部です。したがって、プラグインと集中型サービスの間に存在する「共有」ロジックの多くは、コードの重複をもたらしました。

ここに画像の説明を入力

私は、主要なリファクタリング イニシアチブを実行して、プレゼンテーションに関係のない共通ロジックを「共有」アセンブリに引き出すことにしました。このために、トランクからブランチを作成しました。共通コードを「共有」アセンブリに再編成し、クライアント アプリケーション (プラグインなど) と外部サービス アプリケーションのすべてを再指定して、共有アセンブリを利用しました。多くの場合、今後のより一般的な目的に合わせて、クラスの名前も変更する必要がありました。コア アセンブリは、プラグインと UI の間でプレゼンテーション層の役割を仲介するためだけに残されました。

ここに画像の説明を入力

問題:

リファクタリングが正常に完了したので、ブランチをトランクに再統合したいと考えています。単純なケースでもマージはトリッキーな作業ですが、ここで私が直面しているのは、控えめに言っても多くのツリー競合です。また、まったく新しいプロジェクトに存在することに加えて、「共有」プロジェクトのフォルダー構造は、「コア」プロジェクトのフォルダー構造とはかなり異なります。多くの場合、共有アセンブリを使用するための新しいメカニズムにより、クラスは別の場所に配置されます。

コア アセンブリの古いホームから共有アセンブリの新しいホームまで、すべてのクラスのバージョン履歴を維持したいと考えています。さらに、マージが成功することを保証したいと思います。当たり前のことのように思えますが、このシナリオ全体のミニチュア バージョンをテストしたところ、ブランチの機能が完全に損なわれないような方法で競合を解決することはできませんでした。さらに、以前に述べたように、より一般的な役割に合わせて一部のクラスの名前を変更したという事実により、バージョン履歴の維持が非常に難しくなっています。

ファイルの名前を変更して移動を修復する「通常の」ケースで役立つAnkhSVNを使用していることに注意してください。ただし、これらの主要なツリー競合のケースでは機能しないようです。また、SVN の異なるバージョン間でマージの動作に違いがあることも知っています。SVN 1.5 より前と SVN 1.5 より後のバージョンだと思います。私はSVN 1.9.3を使用しています。

私は今、数週間これを理解しようとしています。私はSVN bookこのような TortoiseSVN のリソース、およびこれこれ、およびこれのような Google 検索から見つけたあらゆるものを注ぎ込んできました。私は夢中になっているように感じます.高度なSVN(およびTortoise)は、従来の自分で教え、Webや本から学ぶアプローチでは学習できないと思います. いずれにせよ、そこにある洞察を大いに感謝します。

SVN を使用して機能ブランチを作成し、大きなツリーの変更と「移動」(名前の変更) を計画して、何も失うことなくそれらの変更をトランクに再統合できるようにする場合、適切な方法論は何ですか?

4

1 に答える 1

0

SVN で最も「人気のある」レーキ - 「リファクタリング後に地獄をマージ」を踏んでおめでとうございます!

苦い経験によって生み出された、あなたのケースには(少なくとも)2つの簡単なルールがあります。

  1. SVN でリファクタリングを実行しない
  2. ルール 1 を無視する場合: 世界で神聖で善良なすべての名において、ブランチでのリファクタリング中にトランクで何も触れないでください。

これらの正しい契約を拒否しても、救いへの道はまだあります

純粋な SVN ウェイ、長くて汚い

Tree Conflict のソースであるすべてのサブツリーをマージし、次のようなすべてのソースとターゲットを手動で決定します

svn merge NEW_PATH/NEW_NAME old_path/old_name

そして、完全なマージによってこれを血まみれの仕事に仕上げます

トリッキーな Mercurial 方式 (または Git 方式ですが、Git は嫌いです)

序文: このようなマージは、最新の DVCS ではまったく問題ありません。SVN リポジトリへの「ブリッジ」があるため、選択した外部 VCS にマージするこのジョブを委任し、結果を返すことができます (いくつかの制限と警告があります)。

私はすべての DVCS について話すのが面倒なので、Mercurial についてのみ説明します (SVN のバックグラウンドがあれば、移行の負担が最も少ないことを考慮してください)。

HGSubversion では、Mercurial は Subversion リポジトリへの読み取り (pull) と書き込み (push) を実行できますが、独自のマージの Subversion 結果にプッシュすることはできません。処理する

簡単なあらすじ

  1. Mercurial (TortoiseHG) と HGSubversion 拡張機能をインストールする
  2. SVN リポジトリ全体を Mercurial の一時的な場所 (現在の Subversion WC ではない) にクローンします。
  3. ブランチをメインラインにマージ (SVN のトランクがdefaultブランチになる)、コンテキストの競合 (ツリーではない) を解決 (可能)
  4. 試験結果
  5. Subversionワーキング コピー (明らかにトランクの WC) を Mercurial ワーキング ディレクトリの内容で完全に置き換え.svnます (それぞれと.hgフォルダに注意してください) 。
  6. WC をトランクにコミットする
  7. 美しさとすべてのルールへの準拠のために、トランクの「チート」mergeinfoデータ(形式的には真実ではありませんが、ステップ6でコミットされ、後でmergesetとして知られる必要があります)

HTH

PS - HGVSを使用した Mercurial への移行は、今のところ完全にクレイジーなアイデアではないようです

于 2016-04-13T02:18:26.683 に答える