(簡単にするために)クライアントとサーバーを備えたアプリケーションがあると仮定しましょう。1つのリポジトリを両方または別々のリポジトリのペアに使用することをお勧めしますか?
それらを混合すると、おそらく相関する変更を追跡し、相関するブランチを維持しやすくなります(つまり、プロトコルの進化)。
(簡単にするために)クライアントとサーバーを備えたアプリケーションがあると仮定しましょう。1つのリポジトリを両方または別々のリポジトリのペアに使用することをお勧めしますか?
それらを混合すると、おそらく相関する変更を追跡し、相関するブランチを維持しやすくなります(つまり、プロトコルの進化)。
回答:
gitまたはmercurialを使用している場合は、サブモジュールまたはサブリポジトリを調べてください。
クライアント、サーバー、およびそれらのインターフェースファイルはそれぞれ独自のリポジトリにありますが、スーパーリポジトリレベルで結び付けられます。これにより、トップレベルで1回のチェックアウトを実行しgit
たりhg
、各サブモジュール/サブリポジトリの適切なコミットをチェックアウトしたりできます。
クライアントとサーバーの両方が互いに適切な場合にのみスーパーリポジトリにコミットすることにより、スーパーリポジトリは動作中のシステムをチェックアウトするオプションのみを提供します-したがって、古いクライアントに対して新しいクライアントを実行しようとすることはありませんサーバーまたはその逆。
サブモジュール/サブリポジトリは、単一のモノリシックリポジトリの利点とともに、個別のリポジトリを使用するすべての利点を提供しますが、少し複雑になります。
この回答は擁護者に意図されていないgit
か、hg
他のSCMの上に、ちょうど私が唯一知っていることを起こるこれらのこのオプションが存在することを知って十分のSCMを。svn
たとえば、外観がどのように機能するのか理解できません。
分ける!
実際、おそらく3つのリポジトリがあります。1つはクライアントおよび対応するクライアント専用ライブラリ、1つはサーバー(および対応するライブラリ)、もう1つは共有ライブラリ(2つの間の機能を公開するAPIインターフェースを組み込む) 、その他の共有コード)。これが本当に重要だと思います。共有コードは独自の別のリポジトリに入れる必要があります。これにより、クライアントとサーバー間の相互運用性が常に同じバージョンであり、各コンシューマーの設計から分離されていることを確認できます。
明らかに、これは、使用している特定の通信フレームワークに応じて常に可能とは限りませんが、データ転送オブジェクトの形式またはカスタムプロトコルのハンドシェイクステップ(または他の例)を指示する共有コードが存在する可能性があります。
かなりまともな継続的インテグレーションとQAのセットアップがあると仮定します(私の経験ではかなり大きな仮定ですが、それでもそれを行います。QA部門がない場合は少なくともCIを取得する必要があります)コードの不一致の可能性を防ぐためにシングルリポジトリパターンを使用する必要はありません。CIサーバーがライブラリの相互運用性にフラグを立てるか、QAチームがランタイムエラーをキャッチします(または、さらに良いことに、ユニットテストがあります)。
分割リポジトリの利点は、システムの個別の部分を個別にバージョン管理できることです。先週のサーバーのコピーを取り、今週のクライアントで実行して、パフォーマンスの問題の根本を突き止めようとしますか?心配ない。
Mercurial、この方式は使用し、使用することができる->
subrepo関係を意味します。
product -> client -|-> (many components)
|-> shared component A
-> server -|-> (many components)
|-> shared component A
製品にはサブリポジトリクライアント、サーバーがあります。それらのそれぞれは、サブリポジトリとしてコンポーネントを持ち、少なくとも2つのサブリポジトリ間で共有される可能性があります。
タグ付けは、おそらくそれより下ではなく、最初の2つのレベルで行う必要があります。
コミットはコンポーネントレベルで行われ、スーパーリポジトリは名前付きブランチと製品のバージョンを効果的に追跡します。通常、名前付きブランチ/ブックマークは、クローンブランチよりも使いやすさ(トレーニングのしやすさ)およびサブリポジトリとの互換性の点で優れています。
hgは、スーパーリポジトリが製品であり、コミットが最上位で行われるという仮定に向かう傾向がありますが、複数の製品が同じコンポーネントを使用する場合は特にうまくいきません。:-)
gitに移行した場合、このスキームが大きく変わるとは思いませんが、まだgitで試していません。
最も単純なアプローチは、複雑さのために複雑のようなので、あなたの場合を除き、単一のリポジトリを使用することで、それはそう説得力のある引数が存在しない場合にデフォルトの選択肢でなければなりません。
クライアントとサーバーの開発は別の組織で行われますか?クライアント(またはサーバー)の実装は複数ありますか?クライアントはオープンソースであり、サーバー実装は秘密ですか?これらのすべての質問に対する答えが「いいえ」である場合、単一のリポジトリよりも複雑なものは、不便さだけをもたらし、利益はありません。
個別のコードベースを維持することを選択した場合、非互換性と依存関係の地獄を避けるために、これがどのように管理されるかについて明確なポリシーが必要になります。最初のいくつかの問題を解決した後、両方のリポジトリを常に一緒にチェックアウトし、一緒にビルドし、一緒に展開することが最も安全なことであることに気付く場合があります...
モジュラリティは素晴らしい特性ですが、リポジトリを分割することはそれを達成するためのツールではありません。前の段落が示すように、複数のコードベースに分割された高度に結合されたコンポーネントを持つことができ(望ましくない)、同様に同じコードベース内に高度にモジュール化されたコンポーネントを持つことができます(望ましい)。
開発と展開を簡素化したため、複数の機会に、チームが既存のgitリポジトリをマージすることを(成功して)提唱しました。
リポジトリについてはしばらく忘れてください。誰かと共有していない場合、マシンで2つのプロジェクトをどのように整理しますか?チームの他のメンバーはどのようにそれを行うでしょうか?あなたは…
クライアントとサーバーの両方のすべてのソースファイルを同じディレクトリに配置しますか?
クライアントとサーバーのサブディレクトリを含むメインプロジェクトディレクトリを作成しますか?
2つのプロジェクトを完全に分離しますか?
チームとしてそれについてコンセンサスを得ると、プロジェクトをコードリポジトリにチェックインする準備が整います。私が考えることができるすべてのリビジョン管理ツールは、好きなディレクトリ構造を喜んで再現します-どのファイルがどのプロジェクトに属しているかについては少しも気にしません。また、1つまたは2つ(または6つ)のリポジトリの違いは、マイナーな管理上の違いを除いて、通常それほど大きくありません。
たとえば、Subversionでは、クライアントとサーバーの個別のリポジトリと単一の結合リポジトリの最大の違いは、リビジョン番号の変更方法にあります。単一のリポジトリでは、クライアントまたはサーバーにコードをコミットするたびにバージョン番号が増加します。個別のリポジトリを使用すると、サーバープロジェクトへのコミットによってクライアントのヘッドリビジョン番号が変更されることはありません。