web-dev-qa-db-ja.com

異なるチームの多くのアプリを含む単一のリポジトリではなく、複数のGitリポジトリを使用していますか?

10年前の大きなCVSリポジトリをGitに移行しています。この複数プロジェクトのリポジトリをいくつかのGitリポジトリに分割することは明らかであるように思われました。しかし、意思決定者はCVSに慣れているため、彼らの見解はCVSの哲学に影響されます。

1つのCVSリポジトリから別のGitリポジトリに移行するように説得するには、いくつかの引数を与える必要があります。

何年もの間Gitリポジトリで作業している仲間と話すとき、複数のGitリポジトリを使用することがGitを使用する方法であると彼らは言います。なぜなのか本当にわからない(アイデアが出てくる)私はこの分野の初心者なので、ここで質問します。

異なるチームの異なるアプリケーションとライブラリを含む単一のGitリポジトリではなく、複数のGitリポジトリを使用するための引数は何ですか?

私はすでにリストしています:


82
olibre

複数のチームと複数のプロジェクトを扱っています。おそらく数十年にわたる作業がコードベースに入りました。

簡単に言えば、チームとプロジェクトにはさまざまなニーズとさまざまな依存関係があるということです。

モノリシックリポジトリアプローチにより、「この構成ではすべてが安定しています!!!」へのコミットが減少します。 (すなわち、多くのチームから供給された非現実的で巨大なコミット)。それ、または多くのプロジェクトの非互換性の多くの中間点。どちらにしても、単純に意図されていなかった構成をサポートするために多くの無駄なエネルギーが費やされています。

代わりに、リポジトリを個別に構成し、依存関係を表す複数のリポジトリを用意する必要があります。依存関係は、開発の適切な時点でプロジェクトの保守担当者が構成、更新、およびテストする必要があります。

  • ProjectAが最後にメジャーリリースしたのは3年前です。メンテナンスモードであり、「古い」システム要件があります。依存関係の適切なセットを参照する必要があります。 20の依存関係があります。
  • ProjectBがリリースされました。最新のシステム要件があり、別のチームによって開発およびテストされました。 15個の依存ライブラリ(= repos)があり、そのうち10個はProjectAと共有されています。これらのプロジェクトは通常、依存するライブラリのさまざまなコミットを参照します。依存関係は、開発の適切な時点で更新されます。
  • ProjectCはまだリリースされていません。これはProjectBに非常に似ていますが、依存関係に対する大幅な変更と改善が含まれています。 ProjectBの開発者は、ProjectCと共有する依存関係の安定リリースを取得することにのみ関心があります。 ProjectBのチームは共有の依存関係にいくつかのコミットを行いますが、現時点では主にバグ修正と最適化です。モノリシックリポジトリは、ProjectAのサポートを維持するためにProjectCの開発を遅らせるか、ProjectCの変更によってAとBが機能しなくなるか、開発者がコードを共有/再利用しないことになります。

複数の(分散)リポジトリを使用すると、各チームは独立して作業し、コードベースを再利用して常に改善しながら、他のプロジェクトへの影響を最小限に抑えることができます。これにより、他のチームから変更があったときに、チームがフォーカス/スピードをシフトすることもできなくなります。一元化されたモノリシックリポジトリでは、各チームがすべてのチームの動きに依存するため、同期する必要があります。

20
justin

このスレッドの大きなレポを支持する議論はないようですので、ここに1つあります:

すべてのコードが含まれている大きなリポジトリの利点は、信頼できる信頼できる情報源があることです。包括的なプロジェクトのすべての状態は、そのリポジトリの履歴に表示されます。 「3か月前からlibBをビルドするには、どのバージョンのlibAが必要ですか?」のような質問について心配する必要はありません。または「スーザンのlibCの変更またはボブのlibDの変更が原因で、統合テストが失敗し始めましたか?」または「evilMethod()の呼び出し元が残っていますか?」それはすべて歴史の中にあります。

関連プロジェクトが別々のリポジトリに分割されている場合、gitはそれらの関係を追跡しません。ビルドシステムは、すべての依存関係のコードを見つける場所、さらに重要なことにビルドするコードのバージョンを知る必要があります。 「マスターからすべてをビルドするだけ」ことができますが、これにより、過去のビルドを再現することが難しくなり、リポジトリ間で同期する必要がある変更(またはロールバック)を行うことが難しくなり、ブランチを安定した状態に保つことが難しくなります。

したがって、問題は「1つの大きなレポまたは多くの小さなレポ」ではありません。それは実際には「1つの大きなリポジトリまたは多くの小さなリポジトリとツーリング」です。どのツールを使用しますか? GoogleのRepo(Android)とgclient(Chromium)は2つの例です。 Gitサブモジュールは別のものです。それらすべてに majordownsides があり、大きなレポの欠点と比較検討する必要があります。

編集:これがいくつかの回答です gitリポジトリ内の単一または複数のプロジェクトから選択しますか?

PS:とにかく、リポジトリを分割したり、他の人のコードを使用したりする必要がある場合のために、うまくいけば物事を改善するためのツールに取り組んでいます: https://github.com/buildinspace/per

38
Jack O'Connor

大きなリポジトリでGitを使用すると、パフォーマンスの問題が発生する傾向があります。

To 引用Linus

そしてgitには明らかにそのようなモデルはまったくありません。ギット
実際には、リポジトリ全体を実際に見ているだけではありません。少し制限したとしても(つまり、一部だけをチェックアウトするか、履歴を少しだけ遡って)、gitは常にすべてを気にし、知識を持ち歩きます。

そのため、すべてを1つのhugeリポジトリとして見るように強制すると、gitは非常にうまくスケーリングしません。その部分は本当に修正できるとは思わないが、おそらく改善できるだろう。

鉱山を強調します。それはあなたの会社のバージョン管理リポジトリが「大規模」であると言っているわけではありませんが、これが人々がGit内で大規模なリポジトリを避ける傾向がある理由の1つです。

35
Brian

彼らは、自分がどのプロジェクトに変更を加えたかを思い出そうとするのではなく、すべてのプロジェクトにわたって自分の変更を示すことを求めています。

Sourcetree (ビールのように自由なGUI Gitフロントエンド)を使用すると、複数のリポジトリを登録し、それらを論理グループに整理して、それらすべてのステータスを一度に表示できます。 screenshot

私はそれらとは何の関係もありません。

22
Ron MacNeil

TL; DR; gitリポジトリに相当するのは、CVSリポジトリではなくCVSモジュールです。

CVSは、リポジトリのサブディビジョンであるモジュールの概念を使用して設計されており、CVSリポジトリは、非常に独立したライフを持​​ついくつかのモジュールで使用するのが一般的です。例として、1つのモジュールに固有であり、別のモジュールには存在しないブランチを持つことは簡単です。

gitはモジュールの概念で設計されていません。各gitリポジトリはCVS用語で1つのモジュールに制限されています。ブランチを作成すると、リポジトリ全体に対して有効になります。

したがって、gitに複数のモジュールが含まれるCVSリポジトリをインポートする場合は、モジュールごとにリポジトリを作成する方がよいでしょう。特に、モジュールに多少独立したライフがあり、ブランチやラベルなどを共有していない場合はなおさらです。 (CVSとgitのブランチの使用パターンが異なるため、CVSブランチごとに1つのリポジトリを用意することの有用性を調査することもできますが、CVSからgitへの移行の場合、最初のワークフローは次のようになるでしょう。苦労する価値のないCVSワークフロー)。

16
AProgrammer

なだめるために彼らと一緒にボールをプレーしたいのなら、あなたはそれを設定することができます this way 。または このメソッド 。それ以外は、システムにアクセスして資産にアクセスするための単一のポイントを期待しているだけだと思います。

"John Smith"は特定のデータにアクセスする必要があり、他のデータには必要ない場合があるため、アクセスのニーズによっては、GITリポジトリを分離した方が良い方法かもしれません。 「Suzy Que」は、すべてへのアクセスを必要とするsys管理者である可能性があります。

単一のリポジトリを使用する場合、内部アクセス要件で問題が発生する可能性があります。それが「誰もが完全にアクセスできる」タイプのものであるなら、私はおそらく彼らの視点を見ることができました。

4
Will Ashworth

Git移行ヘルプページ Eclipseは、CVS/SVNディレクトリツリーを複数のGitリポジトリに再編成することを提案しています。

コード構造をリファクタリングする絶好の機会です。現在のCVS/SVNディレクトリ、モジュール、プラグインなどをGitの新しいホームにマップします。通常、1つのGitリポジトリー(.git)は、プロジェクト、コンポーネントなど、コードの論理グループごとに作成されます。

引数:

ここでのトレードオフは、Gitリポジトリを追加するたびに、開発プロセスに余分なオーバーヘッドが追加されることです。すべてのGitコマンドと操作は、単一のGitリポジトリのレベルで発生します。反対に、各リポジトリー・ユーザーはリポジトリー履歴の完全なコピーを持っているため、非常に大規模なリポジトリーは、不用意な寄稿者にとって扱いにくくなります。

4
olibre

Gitは、現在のサブディレクトリだけでなく、ツリー全体を一度に操作します。

あなたがあなたのプロジェクトを持っているとしましょう

C:\MyCode\ProjectABC

そして、これらの2つのファイルが変更されたとしましょう:

C:\MyCode\ProjectABC\stuff.txt
C:\MyCode\ProjectABC\Stuff\MoreStuff\morestuff.txt

プロジェクトのルートでgitステータスを実行すると、これらのファイルが変更されたことがわかります。

stuff.txt
Stuff\MoreStuff\morestuff.txt

ただし、MoreStuffディレクトリにcdした場合、morestuff.txtファイルのみが表示されますか?いいえ。現在の位置に応じて、両方のファイルが表示されます。

..\..\stuff.txt
morestuff.txt

その結果、すべてのプロジェクトを1つの大きなGitリポジトリにまとめると、チェックインに行くたびにevery projectの変更の中から選択する必要があります。

これを緩和する方法があるかもしれません。たとえば、別のプロジェクトでの作業に切り替える前に、少なくとも一時的に変更をコミットするようにすることができます。しかし、これは、プロジェクトごとに1つのGitリポジトリを使用する場合と比べると、チームの各人が処理しなければならないオーバーヘッドがかなり大きいためです。

3
Kyralessa