web-dev-qa-db-ja.com

gitでは、ダースライブラリのバージョン管理をすべて並行して行う方法

私たちはプロジェクトを行っていますが、プロジェクト間で多くのコードを再利用し、共通のコードを含む多くのライブラリーを持っています。新しいプロジェクトを実装すると、一般的なコードを除外してライブラリに入れる方法が増えます。ライブラリは相互に依存しており、プロジェクトはライブラリに依存しています。各プロジェクト、およびそのプロジェクトで使用されるすべてのライブラリは、参照しているすべてのライブラリと同じバージョンを使用する必要があります。ソフトウェアをリリースする場合、バグを修正し、おそらく数十年、場合によっては数十年にわたって新機能を追加する必要があります。私たちは約12のライブラリを所有しており、多くの場合、変更は2つ以上にまたがっています。複数のチームが複数のプロジェクトに並行して取り組み、これらすべてのライブラリに同時に変更を加えています。

私たちは最近gitに切り替えて、各ライブラリと各プロジェクトのリポジトリを設定しました。 stashを共通のリポジトリとして使用し、機能ブランチで新しい処理を実行してから、プルリクエストを作成し、レビュー後にのみそれらをマージします。

プロジェクトで対処しなければならない問題の多くは、いくつかのライブラリとプロジェクトの特定のコードを変更する必要があります。これらには、多くの場合、互換性のないライブラリインターフェイスの変更が含まれます。 (これが怪しげに聞こえると思われる場合:ハードウェアとのインターフェースをとり、特定のハードウェアを汎用インターフェースの背後に隠します。ほとんどの場合、他のベンダーのハードウェアを統合するたびに、現在のインターフェースが予期していなかった場合に遭遇するため、それらを改良する必要があります。)たとえば、ライブラリP1L1、およびL2を使用するプロジェクトL3を想像してください。 L1L2およびL3を使用し、L2L3を使用します。ディペンデンシーグラフは次のようになります。

   <-------L1<--+
P1 <----+  ^    |
   <-+  |  |    |
     |  +--L2   |
     |     ^    |
     |     |    |
     +-----L3---+

ここで、このプロジェクトの機能がP1L3の変更を必要とし、それらがL3のインターフェースを変更することを想像してください。次に、プロジェクトにP2P3をミックスに追加します。これらもこれらのライブラリーを参照します。それらすべてを新しいインターフェイスに切り替え、すべてのテストを実行し、新しいソフトウェアを展開する余裕はありません。だから代替手段は何ですか?

  1. L3に新しいインターフェースを実装する
  2. L3のプルリクエストを作成し、レビューを待ちます
  3. 変更をマージする
  4. L3の新しいリリースを作成する
  5. P1の新しいリリースを参照するようにすることでL3の機能の作業を開始し、P1の機能ブランチに機能を実装する
  6. プルリクエストを作成し、これをレビューしてマージする

L1L2を新しいリリースに切り替えるのを忘れたことに気づきました。P1と並行して実行する必要があるため、これをどこに固定するかさえわかりません...)

これは退屈でエラーが発生しやすく、この機能を実装するのに非常に長いプロセスです。独立したレビューを行う必要があり(レビューが非常に困難になります)、まったくスケーリングされず、ビジネスが停止する可能性があります。プロセスに行き詰まるので、何も成し遂げられません。

しかし、あまりオーバーヘッドをかけずに新しいプロジェクトに新しい機能を実装できるプロセスを作成するために、分岐とタグ付けをどのように使用しますか?

11
sbi

ここで明白なことを発表するようなものですが、言及する価値があるかもしれません。

通常、git reposは独立している傾向があるため、lib/projectごとに調整されます。プロジェクトを更新し、残りは気にしません。それに依存する他のプロジェクトは、彼らが適切であると思うときはいつでも単に彼らのlibを更新します。

ただし、ケースは相関コンポーネントに大きく依存しているように見えるため、通常、1つの機能がそれらの多くに影響します。そして、全体をバンドルとしてパッケージ化する必要があります。機能/変更/バグを実装するには、多くの場合、一度に多くの異なるライブラリ/プロジェクトを適応させる必要があるため、それらすべてを同じリポジトリに配置することは理にかなっています。

これには強力な利点/欠点があります。

利点:

  • 追跡可能性:ブランチは、この機能/バグに関連するすべてのプロジェクト/ライブラリで変更されたすべてを示します。
  • バンドル:タグを選択するだけで、すべてのソースが正しく表示されます。

欠点:

  • マージ:...単一のプロジェクトでは、すでに厳しい場合があります。さまざまなチームが共有ブランチに取り組んでいるので、インパクトに備える準備ができています。
  • 危険な「おっと」要素:1人の従業員が間違いを犯してリポジトリを混乱させると、allプロジェクトとチームに影響を与える可能性があります。

価格が利益に値するかどうかを知るのはあなた次第です。

編集:

これは次のように機能します。

  • 機能Xを実装する必要があります
  • ブランチを作成feature_x
  • 関係するすべての開発者がこのブランチに取り組み、並行して、おそらくプロジェクト/ライブラリに関連する専用ディレクトリで作業します
  • 終わったら、レビュー、テスト、パッケージ化など
  • それをマスターにマージします...そして、それまでの間、これは難しい部分ですfeature_yおよびfeature_zも追加された可能性があります。 「クロスチーム」マージになります。これが重大な欠点です

記録のためだけに:ほとんどの場合これは悪い考えだと思います。マージの欠点は通常、依存関係の管理や適切な機能の追跡で得られるものよりも高いため、慎重に行う必要があります。

5
dagnelies

あなたが探しているソリューションは、gitサブモジュールと連携する依存関係管理ツールです

次のようなツール:

  • メイベン
  • Composer

これらのツールを使用して、プロジェクトの依存関係を定義できます。

サブモジュールが少なくともバージョン> 2.xxであることを要求するか、互換性のあるバージョンの範囲を示すことができます= 2.2。*または特定のバージョンより古い<2.2.

パッケージのいずれかの新しいバージョンをリリースするたびに、バージョン番号をタグ付けできます。これにより、その特定のバージョンのコードを他のすべてのプロジェクトに取り込むことができます。

4
Patrick

サブモジュール

1つのコメントで提案されているように、 git submodules を試してみてください。

プロジェクトP1が3つのサブモジュールL1L2およびL3を参照する場合、実際には3つのリポジトリすべてに特定のコミットへの参照が格納されます。これらは作業中各ライブラリのバージョンそのプロジェクト用

したがって、複数のプロジェクトが複数のサブモジュールで機能することができます。プロジェクトP1が新しいバージョンを使用している間、L1は古いバージョンのライブラリP2を参照する可能性があります。

L3の新しいバージョンを提供するとどうなりますか?

  • L3に新しいインターフェースを実装する
  • commit、test、プルリクエストを作成、レビュー、マージ、...(これは避けられません)
  • L2L3で動作することを確認し、コミットします...
  • L1が新しいL2で動作することを確認します...
  • すべてのライブラリの新しいバージョンでP1が機能することを確認します。
    • P1のローカルのL1L2およびL3の作業用コピー内で、必要な変更を取得します。
    • 変更をコミットし、git add L1 L2 L3はモジュールへの新しい参照をコミットします
    • P1のプルリクエスト、テスト、レビュー、プルリクエスト、マージ...

方法論

これは退屈でエラーが発生しやすく、この機能を実装するのに非常に長いプロセスです。独立したレビューを行う必要があり(レビューが非常に困難になります)、まったくスケーリングされず、ビジネスが停止する可能性があります。プロセスに行き詰まるので、何も成し遂げられません。

はい、変更するため、 requires independent review、it:

  • 図書館
  • それに依存するライブラリ
  • 複数のライブラリに依存するプロジェクト

あなたががらくたを届けるためにあなたは廃業するでしょうか? (実際はそうではないかもしれません)。はいの場合、テストを実行して変更を確認する必要があります。

適切なgitツール(gitkでも)を使用すると、各プロジェクトが使用するライブラリのバージョンを簡単に確認でき、ニーズに応じて独立して更新できます。サブモジュールは状況に最適であり、プロセスの速度を低下させることはありません。

たぶん、あなたはこのプロセスの一部を自動化する方法を見つけることができますが、上記のステップのほとんどは人間の脳を必要とします。時間を短縮する最も効果的な方法は、ライブラリとプロジェクトをeasyに進化させることです。コードベースが新しい要件を適切に処理できる場合、コードレビューはより簡単になり、ほとんど時間をかけません。

(編集)関連するコードレビューをグループ化することで、もう1つ役立つことがあります。すべての変更をコミットし、それらの変更がすべてのライブラリとプロジェクトに伝達されるまで、プルリクエストを調停する前に(またはそれらを処理する前に)待機します。依存関係チェーン全体の大きなレビューを行うことになります。たぶん、これは、ローカルの変更が小さい場合に時間を節約するのに役立ちます。

0
coredump

だから私が理解しているのは、L1インターフェイスを変更したいが、L3インターフェイスに依存する他のP2とP3をすぐに変更したいP1の場合です。これは、下位互換性の典型的なケースです。これに関する素晴らしい記事があります 後方互換性の維持

これを解決する方法はいくつかあります。

  • 古いインターフェースを拡張できるたびに、新しいインターフェースを作成する必要があります。

OR

  • しばらくして古いインターフェースを廃止したい場合は、いくつかのバージョンのインターフェースを使用でき、依存するすべてのプロジェクトが移動したら、古いインターフェースを削除します。
0
Uday Shankar

私があなたの問題を正しく理解している場合:

  • あなたは4つの相互関連モジュール、P1とL1からL3を持っています
  • 最終的にL1からL3に影響するP1に変更を加える必要があります。
  • 4つすべてを一緒に変更する必要がある場合、プロセス障害としてカウントされます
  • すべて1つずつ変更する必要がある場合は、プロセス障害としてカウントされます。
  • 変更を加える必要があるチャンクを事前に特定する必要がある場合は、プロセス障害としてカウントされます。

したがって、目標は、P1とL1を一度に実行し、1か月後にL2とL3をもう一度実行することです。

Javaの世界では、これは取るに足らないことであり、おそらくデフォルトの作業方法です。

  • すべてが1つのリポジトリに格納され、関連する分岐の使用はありません
  • モジュールはコンパイルされ+バージョン番号に基づいてmavenによって一緒にリンクされます。すべてが同じディレクトリツリーにあるという事実ではありません。

そのため、ディスク上の他のディレクトリにあるP1のコピーに対してコンパイルされた場合にコンパイルされないL3のコードをローカルディスクに置くことができます。幸い、そうではありません。 Javaこれは、ソースコードではなく、コンパイルされたjarファイルに対してコンパイル/リンクテイルが配置されるため、これを直接行うことができます。

C/C++の世界でこの問題に対して広く使用されている既存の解​​決策は知らないので、言語を切り替えたくないと思います。しかし、何かは、同等のことをするmakeファイルと一緒に簡単にハッキングされる可能性があります。

  • インストールされたライブラリ+埋め込まれたバージョン番号を持つ既知のディレクトリへのヘッダー
  • モジュールごとの適切なバージョン番号のディレクトリへのコンパイラパスを変更

mavenでのC/C++サポート を使用することもできますが、ほとんどのC開発者は、あなたがそうした場合に奇妙にあなたを見ます...

0
soru