4

企業環境には、次のような svn リポジトリ構造があります。

root
  libs
    shared_lib1
    shared_lib2
    private_lib
  public_code
  private_code

ここで、public_code は、オープン ソースの外部リポジトリであり、社外の人が読み書きアクセスできる場所です。また、shared_lib1 と shared_lib2 は、他社の別のプログラマー グループと共有する外部リポジトリです。私はメンテナーであり、基本的に技術的に最善のことを行うことができます。外部のユーザーは適応する必要があります。

この構造から Mercurial リポジトリに移動する最善の方法は何かを考えています。

1) Mercurial サブリポジトリを使用して、古いセットアップを厳密にシミュレートできました。または
2) 私たちのために 1 つの大きなレポジトリを作成し、外部パートナーのために 3 つの新しい小さな別のレポジトリを作成し (つまり、基本的にはプロジェクトをフォークします)、大きなレポジトリと別のレポジトリの間でチェンジセットを交換することができます。

svn のセットアップ 1) では、ルートを分岐するときにポリシーにより常に public_code、shared_lib1、および shared_lib2 を分岐する必要があるため、分岐は悪夢です。このために、svn branch を 4 回呼び出し、svn:externals プロパティを手動で 3 回変更する必要があります。Mercurial でメイン リポジトリを簡単に分岐し、すべてのサブリポジトリの新しい分岐を自動的に取得できますか?

セットアップ 2) を行うと、リポジトリ間でファイル システムが異なります。たとえば、レポ "root" に public_code/Makefile がありますが、レポ "public_code" ではファイルは単なる "Makefile" になります。Mercurial はリポジトリ間で変更を同期できますか? ワークフローはどのようになりますか?

4

1 に答える 1

5

SVNのセットアップ1)では、ポリシーにより常に分岐する必要があるためpublic_code、分岐は悪夢です。このために、私は4回呼び出し、プロパティを手動で3回変更する必要があります。Mercurialのメインリポジトリを簡単に分岐して、すべてのサブリポジトリの新しいブランチを自動的に取得できますか?shared_lib1shared_lib2rootsvn branchsvn:externals

いいえ、サブリポジトリはそのようには機能しません。トップレベルリポジトリ内の名前付きブランチは、サブリポジトリに自動的に伝播されません。1.xコードにブランチを作成する場合、ブランチshared_lib1も必要かどうかは明確ではありません1.x。実際、特にライブラリが複数の異なるトップレベルプロジェクトで使用されている場合は、トップレベルコードの分岐と同時に分岐するべきではありません。

セットアップ2)を行うと、ファイルシステムはリポジトリ間で異なります。たとえば、私はpublic_code/Makefileリポジトリrootにありますが、ファイルはちょうどMakefileリポジトリにありpublic_codeます。Mercurialは引き続きリポジトリ間の変更を同期できますか?ワークフローはどのように見えますか?

いいえ、そのように作成した場合、リポジトリ間をプッシュおよびプルすることはできません。リポジトリが同じ「マザー」リポジトリから発信されている場合にのみ、リポジトリ間でプッシュ/プルできます。ここでは、3つの無関係なリポジトリを作成するように聞こえます。


このような状況ではsvn:externals、Subversionにある理由と、それらがMercurialサブリポジトリにどのようにマッピングされるかを慎重に評価する必要があります。の1対1の代替ではありませんsvn:externals。また、サブリポジトリのツールサポートも調べる必要があります。Mercurial自体とMercurialホスティング、継続ビルドシステムなどの両方で、Mercurialサブリポジトリコードの一部を作成しました。Mercurial2.0の時点では、まだいくつかの鋭いエッジがあります。

一言で言えば、サブリポジトリが提供するのは、サブシステム間の非常に緊密な結合です。これは通常避けるべきことです:-)柔軟性が得られるので、ソフトウェアシステムを緩く結合するように努力しています。

サブリポジトリの主なユースケースは、特定のビルドで使用したコンポーネントの正確なバージョンを追跡する「ビルドリポジトリ」です。サブリポジトリ内の特定のブランチの先端を追跡するようにMercurialに依頼することはできません。常に、特定のリポジトリ内の特定のチェンジセットを追跡します。これにより、後で特定のチェックアウトを再作成できます。.hgsubstateファイルは、各サブリポジトリでチェックアウトされた正確な変更セットを追跡します。

したがって、rootリポジトリが開発に使用されず、リリースのビルドにのみ使用される場合、サブリポジトリは実際にうまく機能します。ワークフローは次のようになります

$ cd root
$ cd libs/shared_lib1
$ hg pull
$ hg update 2.0
$ cd ../..
$ make test && hg commit -m "Updated to sharedlib1 2.0"
$ hg tag 2.3

次に、ソフトウェアのバージョン2.3をリリースすると、Mercurialはそれがのバージョン2.0に依存していることを認識していますshared_lib1。サブコンポーネントの責任者から、新しいリリースの準備ができていると言われたときに、これを行うことがあります。もちろん、CIサーバーはこれを毎晩実行して、コンポーネントが連携して動作するかどうかを確認できます。

root開発者が直接作業している場合、およびでの作業の一部としてサブコンポーネントに変更を加えた場合、サブリポジトリはうまく機能しませんroot。これは、コンポーネント間の結合が緊密すぎることを示しています。メインコードがサブコンポーネントの正確なチェンジセットに依存している場合、サブコンポーネントはメインコードに直接含まれている必要があります。また、hg commitトップレベルのリポジトリでは、。の場合、サブリポジトリで同じコミットメッセージが繰り返されて使用されますui.commitsubrepos=True。(デフォルトはMercurial 2.0で変更されFalseました。)これは望ましくない場合が多く、意味がある場合は、サブリポジトリを非常に緊密に結合し、トップレベルのリポジトリの一部にする必要があります。

したがって、要約するrootと、が「ビルドリポジトリ」の場合はサブリポジトリを使用します。それ以外の場合は、最上位リポジトリーのコンポーネントをインライン化するか、Mavenなどを使用して依存関係を管理することにより、コンポーネントをより緩く結合する必要があります。これらのツールでは通常、「最新バージョンrootとそのすべての依存関係をお願いします」と言うことができ、テストに満足したら正式なリリースを作成できます。これらの「スナップショット」ビルドは正確に再現することはできませんが、それも必要ありません。厳密で正確な依存関係の追跡が必要なのは最終リリースだけです。

于 2011-12-26T16:43:03.007 に答える