ほとんどのプロジェクトをモジュール化したgit
環境では、リポジトリごとに1つのプロジェクトに直面していますまたはリポジトリごとに複数のプロジェクトの設計上の問題。モジュール化されたプロジェクトを考えてみましょう:
myProject/
+-- gui
+-- core
+-- api
+-- implA
+-- implB
今日、リポジトリごとに1つのプロジェクトがあります。それは自由を与える
release
個々のコンポーネントtag
個々のコンポーネントしかし、branch
コンポーネントの扱いも面倒です。頻繁に分岐するapi
には、core
に同等のブランチが必要であり、おそらく他のコンポーネントも必要になるためです。
個々のコンポーネントをrelease
したい場合、リポジトリごとに複数のプロジェクトの設計を利用することで、同様の柔軟性を得ることができます。
どのような経験があり、どのように/なぜこれらの問題に対処しましたか?
上記で説明したように、one project per repository
には3つの主要な欠点があります。これらが本当に別個のプロジェクトである場合、これらはそれほど真実ではありませんが、そのサウンドからあるものへの変更はしばしば別のものへの変更を必要とし、これはこれらの問題を本当に誇張する可能性があります:
git bisect
などのツールの使用がはるかに困難になります。それは可能ですが、それほど簡単ではありません。つまり、危機的状況でのバグハンティングは、それよりもはるかに困難です。git log
のような履歴トラバースコマンドは、フラクチャされたリポジトリ構造で意味のある履歴を出力しません。 サブモジュールを使用したいくつかの有用な出力 またはサブツリー、または他のスクリプト可能なメソッドを通じて取得できますが、tig --grep=<caseID>
またはgit log --grep=<caseID>
を入力して、関心のあるすべてのコミットをスキャンすることと同じではありません約。履歴が理解しづらくなり、本当に必要なときに役に立たなくなります。結局、それは機会費用の計算です。以前の雇用主の1つで、主要なアプリケーションを35の異なるサブリポジトリに分割しました。さらに、複雑なスクリプトセットを使用して履歴を検索し、状態(つまり、本番ブランチと開発ブランチ)が同じであることを確認して、個別にまたはまとめてデプロイしました。
それは多すぎた。少なくとも私たちにとっては多すぎる。管理のオーバーヘッドにより、機能が軽快になり、展開がはるかに困難になり、新しい開発者に教えるのに時間がかかりすぎました。そのため、そもそもリポジトリを破壊した理由をほとんど思い出せませんでした。ある美しい春の日、EC2でのクラスターコンピューティング時間の午後に$ 10を費やしました。数十回のgit filter-branch
呼び出しでリポジトリを元に戻しました。私たちは振り返ることはありませんでした。
Christopher リポジトリごとに1つのプロジェクトモデルの欠点を列挙するのに非常に優れた仕事をしました。マルチリポジトリアプローチを検討する理由のいくつかについて説明します。私が取り組んだ多くの環境では、マルチリポジトリのアプローチが妥当な解決策でしたが、リポジトリをいくつ持つべきか、どこでカットするのかを決めるのは必ずしも簡単なことではありませんでした。
私の現在の立場では、10年以上の歴史を持つ巨大な単一リポジトリCVSリポジトリをいくつかのgitリポジトリに移行しました。その最初の決定以来、リポジトリーの数は(他のチームのアクションによって)増加しており、最適なものよりも多くあると私が思うまでになりました。いくつかの新入社員はリポジトリのマージを提案しましたが、私はそれに反対しました。 Waylandプロジェクトにも同様の経験があります。最近私が見た講演では、ある時点で200を超えるgitリポジトリがありましたが、そのことについてリードは謝罪しました。彼らの website を見ると、彼らは5歳であることがわかります。リポジトリへの参加と分割は扱いやすいタスクであり、(妥当な範囲内で)実験しても問題ないことを確認することが重要です。
では、いつ複数のリポジトリが必要になるのでしょうか?
ポイント2と3は、ポイント1が成立する場合にのみ意味があります。リポジトリを分割することで、オフサイトの同僚が被る遅延を大幅に減らし、ディスク消費を減らし、ネットワークトラフィックを改善しました。
4と5はより微妙です。たとえばクライアントとサーバーのリポジトリを分割すると、クライアントとサーバーのコード間の変更を調整するのにコストがかかります。これは、2つの間の分離されたインターフェースを促進するという点で、ポジティブになる可能性があります。
マルチリポジトリプロジェクトのマイナス面があっても、多くの立派な作業がそのように行われます-ウェイランドとブーストが頭に浮かびます。ベストプラクティスに関するコンセンサスがまだ発展していないと思います。ある程度の判断が必要です。複数のリポジトリ(git-subtree、git-submoduleなど)を操作するためのツールは、まだ開発および実験中です。私のアドバイスは、実験して実用的になることです。
GitHubを使用しているため、実際には1つのリポジトリに複数のプロジェクトがありますが、ensureそれらのプロジェクト/モジュールは適切にモジュール化されています(-apiおよび-core規則+ Maven +静的およびランタイムチェックを使用し、 OSGiの1日で起動します)。
それは何を節約しますか?複数のプロジェクトで小さなものを変更する場合は、複数のプルリクエストを発行する必要はありません。問題とWikiは一元管理されます。
私たちは依然として各モジュール/プロジェクトを適切な独立したプロジェクトとして扱い、CIサーバーなどに個別にビルドして統合します。
私にとって、1つ以上のリポジトリを使用する主な違いは、次の質問に対する答えです。
例として、私はSubversionリポジトリの「品質」をチェックする小さなアプリケーション(クライアントのみ)を持っています。コマンドラインから開始できるコア実装があり、Java 6で適切に動作します。しかし、私はJavaの一部としてJavaFXを使用するUIの実装を開始しました8.それで、2つを分割し、別のスケジュールで(2番目のビルドプロセスで)2番目のリポジトリを作成しました...
上記の回答は気に入っています(投票したものです)が、それは本当の話ではありません。そのため、リポジトリを分割するための引数も追加したいと思いました。したがって、実際の答え(いつ分割するか)は途中のどこかにあるかもしれません...
git-subtree ( Atlassian blog 、 medium blog 、または kernel link を参照)は、あなたが持っているものにぴったりです。したがって、最上位のプロジェクトはそれぞれ、異なるバージョンのサブツリーのセットを使用します。
あなたの例から、リポジトリはそれらがどのように相互依存しているかという観点で設定されるべきです。 MicroServicesとドメインドリブンデザインの設計に関するすべての理由がここに当てはまります。場合によっては、重複したコードが許容され、インターフェースを操作し、本当に必要でない限り互換性を壊さないことなどです。
私の見解では、UIはバックエンドから独立しているはずです。そのため、UIプロジェクトリポジトリには通常、UIコードとクライアントコントローラが含まれている必要があります。クライアントコントローラーは、抽象的な方法でサービスコントローラーに接続します。サービスとは別にバージョン管理されるサービスクライアント/ API抽象化を使用するため、クライアントを壊すことなくサービスを更新できます(複数の異なるクライアントが存在する可能性があります)。
したがって、サービス自体は独自のリポジトリでなければなりません。私の考えでは、このサービスは、単一の通過点ビジネスロジックのラッパーにすぎません。そのため、ビジネスロジックは通常、それをホストするサービステクノロジーとは別にする必要があります。一方、リポジトリの実装は通常、ビジネスロジックに密接に接続されているため、同じリポジトリに統合できます。しかし、そこにあなたの走行距離は異なる場合があります。
もちろん、テクノロジーや複数のスタックのサポートの点で大幅に変更される可能性が低い単純なプロジェクトでは、すべてのUIをバックエンドと同じソースからホストでき、バックエンドサービスは通常、同じクライアントでのみ使用されます。緊密に統合されたリポジトリ。
その場合は、たぶん1つのリポジトリに完全なバーティカルを配置するだけで問題なく、機能ドメインが独自のリポジトリで適切にスタンドアロンであることを確認することに焦点を当てます。その場合でも、リポジトリが小さいというほとんどの利点があり、それ以外の場合はオーバーヘッドがほとんどありません。