共通のネストされたサブモジュールを使用してGitリポジトリを整理する


50

私はGitサブモジュールの大ファンです。バージョンとともに依存関係を追跡できるので、以前のバージョンのプロジェクトにロールバックし、対応するバージョンの依存関係を安全かつクリーンに構築できます。さらに、ライブラリの履歴は、ライブラリに依存している(およびオープンソース化されない)アプリケーションの履歴とは別個であるため、ライブラリをオープンソースプロジェクトとしてリリースする方が簡単です。

仕事中の複数のプロジェクトにワークフローを設定していますが、単一のモノリシックプロジェクトではなく、このアプローチを少し極端にするとどうなるか疑問に思っていました。サブモジュールを実際に使用すると、ワームの潜在的な可能性があることにすぐに気付きました。

一対のアプリケーション:studioおよびplayer、および依存ライブラリcoregraphおよびを想定します。network依存関係は次のとおりです。

  • core スタンドアロンです
  • graphcore(サブモジュール./libs/core)に依存
  • network上のcoreサブモジュール(サブモジュール./libs/core
  • studio依存graphし、network(サブモジュールに./libs/graph及び./libs/network
  • player依存graphし、network(サブモジュールに./libs/graph及び./libs/network

CMakeを使用しており、これらの各プロジェクトに単体テストとすべての作品があると仮定します。各プロジェクト(studioおよびを含むplayer)は、コードメトリックス、ユニットテストなどを実行するためにスタンドアロンでコンパイルできる必要があります。

事は、再帰的git submodule fetchであり、次のディレクトリ構造を取得します:

studio/
studio/libs/                    (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/         (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/       (sub-module depth: 2)
studio/libs/network/libs/core/

プロジェクトでcore2回複製されていることに注意してくださいstudio。このディスクスペースの浪費とは別に、core2回ビルドするため、ビルドシステムの問題が発生しますcore

質問

共通のネストされたサブモジュールの複数のコピーを取得せずに、バージョン付きの依存関係とスタンドアロンビルドを取得できるように、サブモジュールを整理するにはどうすればよいですか?

可能な解決策

ライブラリの依存関係がある程度示唆されている場合(つまり、「バージョンXで動作することがわかっている」または「バージョンXのみが公式にサポートされている」方法)次のシナリオを想像できます。

  • ビルドシステムを用意しgraphnetworkどこで見つけるかを伝えますcore(たとえば、コンパイラインクルードパスを使用して)。「standalone」と「dependency」の2つのビルドターゲットを定義します。「standalone」は「dependency」に基づき、ローカルcoreサブモジュールを指すインクルードパスを追加します。
  • 追加の依存関係を導入studiocoreます:on 。次に、studiobuilds corecoreサブモジュールの独自のコピーへのインクルードパスを設定し、ビルドgraphnetworkて「依存関係」モードにします。

結果のフォルダー構造は次のようになります。

studio/
studio/libs/                    (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/         (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/       (empty folder, sub-modules not fetched)

しかし、これは(更新は、いくつかのビルドシステムの魔法(私はこれがCMakeので行うことができますかなり確信しています)およびバージョンアップの一部に手作業のビットを必要とするgraphも、更新が必要な場合がありますcorenetworkの互換性のあるバージョンを取得するためにcore、すべてのプロジェクトで) 。

これについて何か考えはありますか?


この問題はcmakeに固有のものではないことに注意してください。システムを含まないビルドシステムにも存在します。(すなわち、スーパープロジェクトはちょうどライブラリソースを追加することを意図していますとき、ヘッダのみのライブラリを含む)
MM

回答:


5

私はこのパーティーに非常に遅れていますが、あなたの質問はまだ完全な答えを持っているようには見えません、そしてそれはグーグルからかなり顕著なヒットです。

C ++ / CMake / Git / Submodulesでもまったく同じ問題があり、MATLAB / Git / Submodulesでも同様の問題があります。MATLABがコンパイルされていないため、さらに奇妙な問題が発生します。最近、このビデオに出会いましたが、これは「解決策」を提案しているようです。このソリューションは基本的にサブモジュールを破棄することを意味するため、このソリューションは好きではありませんが、問題は解消されます。@errordeveloperが推奨するとおりです。各プロジェクトにはサブモジュールはありません。プロジェクトをビルドするには、スーパープロジェクトを作成してビルドし、依存関係の兄弟として含めます。

したがって、開発プロジェクトは次のgraphようになります。

buildgraph/graph
buildgraph/core

その後、スタジオのプロジェクトは次のようになります。

buildstudio/studio
buildstudio/graph
buildstudio/network
buildstudio/core

スーパープロジェクトは、メインCMakeLists.txtとサブモジュールの束にすぎません。ただし、サブモジュール自体のプロジェクトはありません。

このアプローチにかかる唯一のコストは、実際のプロジェクトの構築に専念している些細な「スーパープロジェクト」の急増です。そして、誰かがあなたのプロジェクトの1つを手に入れた場合、スーパープロジェクト、その依存関係を見つけることなく簡単に伝える方法はありません。たとえば、Githubで見た目がひどい場合があります。


1

サブモジュールgraphとの両方を統合する場合、の履歴内の特定の時点で常に同じバージョンを持っている必要があります。サブモジュールをにリンクします。networkstudiocorestudiostudio/libs/corestudio/libs/{graph,network}/libs

更新:

あなたが述べた依存関係で複数のリポジトリを作成しました:

./core      <--- (v2)
./graph
./graph/libs
./graph/libs/core  <--- (v2)
./graph/.gitmodules
./network
./network/libs
./network/libs/core  <--- (v1)
./network/.gitmodules
./studio
./studio/libs
./studio/libs/graph
./studio/libs/graph/libs
./studio/libs/graph/libs/core <--- (v1)
./studio/libs/graph/.gitmodules
./studio/libs/network
./studio/libs/network/libs
./studio/libs/network/libs/core  <--- (v1)
./studio/libs/network/.gitmodules
./studio/studio
./studio/.gitmodules

v1v2は、2つの異なるバージョンですcoregraphハンドルバージョン2、一方networkのニーズいくつかの作業とは、バージョン1でスタックされstudio、ローカル埋め込みバージョンcoreの両方の点v1作業プログラムを有するためです。現在、ビルドの観点を除き、すべてがサブモジュールで適切に機能します。

次のディレクトリを削除できます。

./studio/libs/network/libs/core

そして、それをシンボリックリンクに置き換えます:

./studio/libs/network/libs/core@ -> ../../graph/libs/core/

この変更をローカルでコミットすると、coreinsideの2つの異なるバージョンを使用する機能が失われますがstudio、ビルドはcore1回だけです。にアップグレードする準備ができたらv2、次のことができます:

 git submodule update # (--rebase ?)

... studio / libs / network内。


シンボリックリンクのアイデアは私の頭をよぎったが、それは解決策ではない。graph/libs/core外部からリンクする場合、サブモジュールは使用していません。studio/libs/coreサブモジュールの独自のライブラリの1つにリンクする場合、graphどちらを選択しますかnetwork?さらに、3層以上の深さになるとどうなりますか?最後に、もしもcoreある範囲のリビジョンになる場合があります。それはあなたがいずれかのバージョンにリンクすることは明らかではないcoreことgraphと、network使用しています。
アンドレキャロン

「どちらを選びますか?」:coreは、元のcoreライブラリからフェッチされ、両方graphと互換性のあるバージョンに更新されたサブモジュールになりますnetwork(どちらが適切かを判断する必要があります)。シンボリックリンクは、ローカルモジュールgraphnetworkサブモジュールに追加されます(フェッチされません)。
コアダンプ

1
シンボリックリンクは、あなたがに追加することを提案graphしてnetwork(たとえば、どこかで自分のリポジトリ外を指しますstudioプロジェクト)。シンボリックリンクを使用する場合と、独自のサブモジュールを使用する場合をどのように知るのですか?おそらく、あなたの考え方を示すために例を追加する必要があります。
アンドレキャロン

0

サブモジュールの深さが1つになるようにフラット化して、すべてのモジュールをサブモジュールとして保持し、READMEとビルドスクリプト以外は何も保持しないリポジトリを用意します。依存関係をリンクするパッケージごとに個別のビルドスクリプトがあります。それ以外の場合は、パッケージ用に個別のリポジトリを作成できます。


1
私の投稿でこれが明確であったかどうかはわかりませんが、同じライブラリに依存する複数のアプリケーションがあり、アプリケーション全体でライブラリのビルドスクリプトを複製したくありません。
アンドレキャロン

3
答えを詳しく説明して、さまざまな問題にどのように対処するかを示す必要があります。コンテキストによっては依存ライブラリが同じ場所にないため、依存関係をどのようにリンクするかは明確ではありません。
アンドレキャロン

0

サブモジュールは使用しません。

魅力的で、svn-externalsの場合と同じです。ただし、リンクするこれらのプロジェクトがすべて1年間同じ場所にあることを確認できますか?5つはどうですか?

したがって、必要なすべての依存関係をプロジェクトにコピーするだけです。これは、レポが有効である限り、正確な状態をチェックアウトできることを意味します。

基本的に、次のようなフォルダー構造があります。

myproject/... [sources etc]
ext/ [third-party dependencies]


e.g. ext/boost, ext/cppunit

これはディスク領域の観点からはあまり良いことではありませんが、リポジトリがより高いレベルで利用可能である限り、記録されたすべての状態をチェックアウトできるという保証を高く評価しています。

さらに、ここで説明するように、サブモジュールには多くの問題があります


私はそれらをすべて維持しているので、彼らは正しい場所にいると確信しています:-)また、再配布条件のためにプロジェクトをコピーすることにも注意してください。
アンドレキャロン

OK、それは問題を軽減します。ライセンス供与:はい、注意する必要がありますが、それはまったく別の問題です。
ウィルバート

0

ここでまったく同じ問題に直面しています。解決策の1つは、いくつかのレポ持っている可能性がlibs開催するcorenetworkgraphサブモジュールとその依存関係を見つけるためにLIBSのそれぞれを言うだろうちょうどCMakeListsとして。各アプリケーションはlibsサブモジュールとして使用され、必要なライブラリのみを使用します。

各ライブラリのテストは、2つの方法でセットアップできます。

  • core_testing、graph_testing、network_testingを個別のアプリケーションとして持つ
  • テストされたライブラリをテストサーバーにデプロイし、cmakeを使用してテストを実行しながらそれらを見つけます

これにより、すべてのライブラリが他のすべてのライブラリで利用可能になりませんか?
アンドレキャロン

デフォルトでは、はい。しかし、それはlibsレベルのcmakelistsで決定できます。graphについて知る必要がない場合network- サブディレクトリにnetwork関連するものを渡さないでくださいgraph
最大
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.