重い企業通信、構成管理およびテスト要件を備えたMercurialリポジトリ構造


16

私は、分散バージョン管理のタオで自分自身を再教育するのに苦労している別のSubversionユーザーです。

Subversionを使用するとき、私はプロジェクトマイナーアプローチの大ファンであり、以前の雇用主のほとんどと一緒にリポジトリブランチを構築しました。次のようなタグとトランク:

branches-+
         +-personal-+
         |          +-alice-+
         |          |       +-shinyNewFeature
         |          |       +-AUTOMATED-+
         |          |                   +-shinyNewFeature
         |          +-bob-+
         |                +-AUTOMATED-+
         |                            +-bespokeCustomerProject
         +-project-+
                   +-shinyNewFeature
                   +-fixStinkyBug
tags-+
     +-m20110401_releaseCandidate_0_1
     +-m20110505_release_0_1
     +-m20110602_milestone
trunk

実際のソースツリー内では、次のような構造(のようなもの)を使用します。

  (src)-+
        +-developmentAutomation-+
        |                       +-testAutomation
        |                       +-deploymentAutomation
        |                       +-docGeneration
        |                       +-staticAnalysis
        |                       +-systemTest
        |                       +-performanceMeasurement
        |                       +-configurationManagement
        |                       +-utilities
        +-libraries-+
        |           +-log-+
        |           |     +-build
        |           |     +-doc
        |           |     +-test
        |           +-statistics-+
        |           |            +-build
        |           |            +-doc
        |           |            +-test
        |           +-charting-+
        |           |          +-build
        |           |          +-doc
        |           |          +-test
        |           +-distributedComputing-+
        |           |                      +-build
        |           |                      +-doc
        |           |                      +-test
        |           +-widgets-+
        |                     +-build
        |                     +-doc
        |                     +-test
        +-productLines-+
        |              +-flagshipProduct-+
        |              |                 +-coolFeature
        |              |                 +-anotherCoolFeature
        |              |                 +-build
        |              |                 +-doc
        |              |                 +-test
        |              +-coolNewProduct
        +-project-+
                  +-bigImportantCustomer-+
                  |                      +-bespokeProjectOne
                  |                      +-bespokeProjectTwo
                  +-anotherImportantCustomer-+
                                             +-anotherBespokeProject

アイデアは、リポジトリの構造を使用してエンジニアリングチーム間のコミュニケーションの構造化を支援することでした(現在もそうです)。ビジネスの顧客対応部分およびその他のさまざまな利害関係者とドメインの専門家。

言い方をすれば、「プロジェクト」ディレクトリの1つにあるソースドキュメントは、一度しか使用されません(そしてお金を稼ぎます)。「productLines」ディレクトリの1つにあるドキュメントは、その特定のラインの製品が販売されるたびにお金を稼ぎます。「ライブラリ」ディレクトリの1つにあるドキュメントは、それを使用する製品が販売されるたびにお金を稼ぎます。

これにより、コストの償却という概念が明確になり、ビジネス全体でソースドキュメントの再利用のサポートを構築できます。

また、ビルド自動化ツールが動作できる共通の構造があることも意味します。(私たちのビルドスクリプトは、各コンポーネントのビルド方法を指定する構成ファイルを見つける「ビルド」フォルダーを探してソースツリーを歩きます。ドキュメントの生成とテストでも同様のプロセスが発生します)。

重要なことに、私が作業している製品は通常、パフォーマンス測定と特性評価テストを実行するのに長い時間がかかります。20〜200時間。数GBから数TBの処理済みテスト結果/中間データのいずれかを生成します(保存して特定のシステム構成に結び付けて、経時的なパフォーマンスの向上を測定する必要があります)。この問題により、構成管理が重要な考慮事項になり、通常、パフォーマンス測定と特性評価テストの実行に必要な計算リソースが制限されるため、集中化のための要件も課されます。(64〜128コアの小さなクラスター)。

最後のメモとして。継続的インテグレーションシステムは、ビルドをトリガーする必要があることを知っています。静的分析; トランクが変更されるたび、「タグ」ブランチが変更されるたび、および「自動化」ブランチブランチが変更されるたびに、スモークテストとユニットテストが実行されます。このようにして、個々の開発者は個人システムで重要な機能であるIMHOでCIシステムを使用できます。

さて、ここに私の質問があります:Mercurialで、上記のすべてをどのように複製できますか(できればそれを改善できますか)。

-編集:

私の現在の考え方は、中央のSubversionリポジトリを使用して全体的な構造を定義することですが、クライアントとしてhgを使用できるようにして、開発者がローカルでリポジトリを利用できるようにすることです。


1
ワオ。これに対する良い答えは、非常に長いエッセイになると思います。
エドジェームズ

重要な問題は、おそらく最も抵抗の少ないパスを定義するコードマージの方法と場所です。それでは、コードはどのようにマージされますか?
ワイアットバーネット

通常、マージは個人ブランチからプロジェクトまたは機能ブランチへ、そしてトランクへ行われます。トランクに統合せずに長時間(最大1回の反復)実行したことはありませんが、マージで多くの困難を経験したことはありません(Win32でTortoiseSVNを使用していました)。いずれにせよ、ほとんどの作業をトランクで行う傾向がありましたが、目標は開発ワークフローではなく、人の管理を簡素化することでした。(開発者が1人、独立して作業する開発者が多いため、トランクにすべてを入れることで、開発者が何が起きているかを追跡しやすくなりました。)
ウィリアムペイン

重要なポイントの1つは、特にシステムテストレベルで、CIシステムが推進するテストに大きく依存していたことです。これは、さまざまな開発者が互いに干渉していないという自信を高め、多数の小さな反復のメンタリティを促進するためでした。(また、システムテストを実行するのに必要な計算量の増加は、人々が主にトランクで作業する場合の計算リソースの競合が少ないことを意味していました)。
ウィリアムペイン

回答:


10

Spoikeの答えは素晴らしいですが、コメントするには大きすぎるものを追加する価値があると思ういくつかの事柄があります。

支店組織

Mercurialを使用すると、最初の組織図全体を喜んで無視できます。Spokeによると、各リポジトリには独自のタグ、ブランチ(名前付きおよび匿名)のセットがあり、ビジネスニーズに応じて整理できます。

ライブラリのbespokeProjectTwo特別なバージョンが必要な場合は、chartingブランチしcharting、新しい機能を追加してで使用しbespokeProjectTwoます。新しい機能(およびそのバグ)は、標準chartingライブラリを参照する他のプロジェクトでは使用されません。メインchartingライブラリのバグが修正されている場合は、それらの変更をブランチにマージできます。他のプロジェクトでもこれらの機能が必要な場合は、それらのプロジェクトで特別なブランチを使用するか、ブランチをメインラインにマージしてブランチを閉じることができます。

また、AUTOMATIONブランチなどの特定の機能を提供するためにブランチ名を構造化するポリシーを持つことを妨げるものは何もありません。

ディレクトリ構成

Mercurialの場合とまったく同じようにソースディレクトリを保持できない理由はありません。唯一の違いは、Subversionでは単一のモノリシック(src)リポジトリを使用するのに対し、Mercurialでは論理的にグループ化されたリポジトリに分割した方がよいということです。ソースツリー構造から、おそらく次のそれぞれを個別のリポジトリとして抽出します。

src-+
      +-(developmentAutomation)
      +-libraries-+
      |           +-(log)
      |           +-(statistics)
      |           +-(charting)
      |           +-(distributedComputing)
      |           +-(widgets)
      +-productLines-+
      |              +-(flagshipProduct)
      |              +-(coolNewProduct)
      +-project-+
                +-bigImportantCustomer-+
                |                      +-(bespokeProjectOne)
                |                      +-(bespokeProjectTwo)
                +-anotherImportantCustomer-+
                                           +-(anotherBespokeProject)

これにより、任意の製品またはカスタムプロジェクトで、任意のリビジョンでライブラリの任意の組み合わせを使用できます。製品またはプロジェクトの特定のバージョンに使用されるライブラリを管理する簡単な方法については、水銀サブリポジトリご覧ください。

ワークフロー

Spoikeが推奨するワークフロー(開発者が祝福されたレポからプルし、ローカルで動作し、プルリクエストを発行し、最後にインテグレーターがそれらの変更をプルしてマージする)の代替手段は、継続的な統合システムを仲介として使用することです。

前と同じように、開発者は祝福されたレポからプルしてローカルで動作しますが、完了したら、祝福されたレポから再びプルし、祝福されていないレポにプッシュする前に自分自身をマージします。祝福されていないレポへの変更は、(手動または自動で)レビューされ、承認された場合にのみ祝福されたレポに移動されます。

つまり、インテグレーターは変更を受け入れるか拒否するだけで、マージは行いません。私の経験では、コードを書いた開発者がマージを実行する方が、他の誰かがそれを実行するよりも、ほとんど常に優れています。

Mercurial Bookで提案されているように、フックを使用してこの手順を自動化できます。

誰もがプルするサーバーに変更セットをプッシュすると、サーバーは変更セットをテストしてから永続的に受け入れるようにし、テストスイートに合格しない場合は拒否します。ユーザーがこのフィルタリングサーバーから変更を取得するだけの場合、ユーザーが取得するすべての変更が自動的に審査されるようになります。

その他の問題

大規模なテストデータセットの問題は、そのテストデータを水銀サブリポジトリに入れることでも解決できます。これにより、テストデータのリビジョン管理を維持しながら、コードリポジトリがテストデータで肥大化するのを防ぎます。


繰り返しますが、別の優れた有益な答えです。ありがとうございました。
ウィリアムペイン

RE:ブランチ組織。最初の組織図は喜んで無視できることに同意します。とにかく、それはワークフローを特にうまく伝えなかったので、慣習を強化する以上の実際のユーティリティを提供しませんでした。ただし、(可能な限り)ワークフローを強力に伝え、頻繁なコミットを奨励するものに置き換えたいと思います。おそらく、メインの "trunk / development"ブランチを "daily"と呼ぶのはどうでしょうか?
ウィリアムペイン

RE:ディレクトリ組織。コミュニケーションのサブリミナル手段としてソースディレクトリ組織を使用していました。コードの組織に暗黙的な構造を課します(そして、それを通じてビジネス全体に)。Mercurialは非常に柔軟に使用される傾向があることを理解し始めています。しかし、ワークステーションとネットワークストレージエリアでドキュメントを整理する方法に構造を課すことで、人々がビジネスについて考える方法に構造を課すために、その柔軟性の一部を本当に抑えたいと思っています。(ハイテクよりも、企業の途切れが。)
ウィリアム・ペイン

RE:ワークフロー。最も簡単なワークフローは、「毎日の」リポジトリからプルし、ローカルで作業し、(頻繁に)「毎日の」リポジトリにプッシュバックし、CIシステムを介して静的分析、スモークテスト、回帰テストを開始することだと思います。メインリポジトリが「壊れた」状態になっているのは、それについて知っている限り、またすぐに修正される限りはうれしいです。実際、頻繁なコミットと良好なテストカバレッジを促進するために、「毎日」リポジトリへのコミットをコンパイルおよびビルドできる唯一の方法にすることを検討しています。(孤立して仕事をする能力よりもはるかに重要です、私見)。
ウィリアムペイン

@WilliamPayne-ありがとう。Mercurialは柔軟性がありますが、適切なリポジトリ、ブランチ、フックを使用して、組織レベルまたはリポジトリレベルで必要な制限を組み込むことができます。個人的には、単に組織のコントロールといくつかのCIフックから始め、それらのコントロールの必要性が明らかになったら将来的に拡張します。また、サブレポを慎重に使用すると、たとえば、サーバー上と同じ構造でローカルに物をチェックアウトすることを奨励できます。たとえば、スーパーレポを使用するproductLinesbigImportantCustomer、スーパーレポとして使用できます。
マークブース

9

さて、これに単純に答えようとしています。

知っておくべきこと

最初に知っておくべきこと:Mercurialは分散バージョン管理であり、以下にリストされているいくつかのプロパティがあります。

  • ソースは1つのリポジトリから取得され、そのリポジトリを複製できます。複製されたすべてのリポジトリーは、同期によってコードを相互に共有できます(プルコマンドとプッシュコマンドを使用し、アクセスを制限できます)。
  • コードのコピーを持っているすべてのユーザーは、リポジトリのクローンを持っています。分岐したい場合は、ローカルクローンで実行できます。つまり、すべてのユーザーが分岐する方法を整理する必要はありません。彼らは自分でこれを行うことができます。
  • タグはコミットによってMercurialで作成されます(これはgitのハードタグと同じです)。つまり、タグのリポジトリ構造内にディレクトリは必要ありません。
  • 人々がDVCS(githubおよびbitbucketで採用されている)で作業する通常のモデルは、それを半集中的に行うことです。

    各ユーザーには、パブリックリポジトリ(一部の共有または安全なサーバー)とプライベートリポジトリ(自分のワークステーション)があります。どちらもインテグレーターの「祝福された」リポジトリーのクローンです。コードを公開する準備ができたと感じるときはいつでも、変更を公開リポジトリにプッシュできます。インテグレーターは、「祝福された」リポジトリーにコードを取り込むユーザーを選択できます。

    インテグレーターがユーザーのコードを簡単にマージできない場合、変更は拒否され、リポジトリを更新してマージを修正するのはその特定のユーザー次第です。頻繁にマージする場合(マージする必要のあるコードが少ないため)、通常はそれほど難しくありません。通常、ユーザーはマージの問題点を知る必要があります。

プロジェクトごとのリポジトリ設定

したがって、通常の設定では、各プロジェクトに次のものがあります。

  • インテグレーターが担当する読み取り専用の公開リポジトリ。それは「祝福されています」。

    つまり、すべてのユーザーはコンテンツをプル/フェッチできますが、プッシュするアクセス権はありません。

  • 各ユーザーは、リポジトリの独自のパブリッククローンを持つことができます。

    共有ドライブに入れてセットアップするのが最も簡単です(ただし、bitbucketなどのホスティングを検討することもできます)。インテグレーターはユーザーからプルリクエストを受け取り、これらのリポジトリから新しいコードをプルしようとします。マージが問題なく実行されると、読み取り専用リポジトリに配置されます。そうでない場合、ユーザーはローカルで更新およびマージすることで発生するマージの競合を修正するよう求められます。

  • 各ユーザーは、リポジトリの独自のプライベートクローンを持つことができます。

    パブリッククローンからプルすることをお勧めしますが、パブリックまたはインテグレーターからプルするかどうかは関係ありません。すべてのコミットは一意に識別可能であるため、パブリックでフェッチするのを忘れたコミットをマージすることは比較的簡単に修正できます(プライベートからパブリックに変更をプッシュすることにより、インテグレーターの変更も自動的に取得されます)。

ソースコードの構成

プロジェクトソース自体をどのように配置するかについては、熟考する必要があります。アーティファクトをソース管理する必要がある場合は、ソース管理に入れます。個人的には、バイナリやログファイルなど、ビルドまたはランタイムによって作成されたアーティファクト(これらの種類のアーティファクトのマージ競合のリスクが高いため)をチェックインするという考えは好きではありません。

開発者が簡単に始められ、リリースやライブ/実稼働環境の設定を混乱させない限り(アプリ/ Webサーバー設定など)、設定をチェックインすることもできます。これは、コードをチェックアウトしてから5分以内に開発者が開始することを深刻に妨げる構成がある場合、リファクタリングする必要があるという概念につながります。もう1つの要件は、開発者がリリース環境またはライブ/実稼働環境を台無しにするのが難しいことです。

コードの特定のバージョンに関連付ける必要があるテストデータがあることを言及します。MercurialやGitなどのDVCSシステムは、巨大なデータをチェックインすると遅くなる傾向があるため、これは少し複雑です。私の経験では、5 GBのバイナリファイルの後で本当に耐えられません(マイレージは異なる場合があるため、どのように機能するかをテストする必要があります)。ただし、生成されたデータを独自のリポジトリに配置し、チェックイン時にテストシステムに適切にタグ付けする(および/または同じメタデータ用のテキストファイルを作成する)ことをお勧めします。

これがすべて理にかなっていることを望みます。詳細がわからない場合や、さらに説明が必要な場合は編集してみてください。


+1は、いくつかの非常に有用なポイントを備えた非常に優れた応答です。あなたの答えの最初のセクションに応えて、私は各ユーザーが自分のパブリックリポジトリを持つことの重要性を把握していませんでした。おそらく、ピアツーピアワークフローをどのように編成できるかについてさらに考える必要があります。
ウィリアムペイン

あなたの答えの2番目のセクションに応えて、組織全体の単一のリポジトリを持つことの全体的なポイント(私の考えでは)は、仕事がどのように構造化されているかについて共有された精神的なイメージを作成し、できるコンポーネントを見つけやすくすることです再利用されます。(バザーではなく大聖堂ですが、それが私が働いている環境です)。DCVSで同じ構造の組織(ファイリングシステム)を実現する方法を知りたいと思います。
ウィリアムペイン

あなたの答えの3番目のセクションへの回答:ソース管理システムはソースドキュメント用であり、派生したアーティファクトはそこに属さないことに心から同意します。また、VCSに記述の大きなバイナリを保存することは実用的ではないことに同意します。ただし、定義済みの名前を使用して、合意済みのネットワークロケーションに大きなバイナリを格納し、VCS内から参照できると考えています。たとえば、ビルド環境を名前付きVMディスクイメージとして保存し、さまざまなビルドスクリプトから参照できます。(例:build_env_Aでビルドしてください)。同じことがテストデータにも当てはまります。
ウィリアムペイン

過去に、ネットワークドライブ上のディレクトリ階層を使用しました。ディレクトリ名は、サブバージョンリビジョン番号+ブランチロケーションのハッシュから派生し、中間ファイルとテスト結果を特定のリビジョンに結び付けます。これは、バージョン管理に派生ファイルを保存する必要なく、トレーサビリティがあることを意味します。
ウィリアムペイン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.