web-dev-qa-db-ja.com

一般的なネストされたサブモジュールでGitリポジトリを整理する

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

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

アプリケーションのペアを想定すると、studioplayer、および依存ライブラリcoregraphnetwork、依存関係は次のとおりです。

  • coreはスタンドアロンです
  • graphcoreに依存します(./libs/coreのサブモジュール)
  • networkcoreの詳細(./libs/coreのサブモジュール)
  • studiographおよびnetworkに依存します(./libs/graphおよび./libs/networkのサブモジュール)
  • playergraphおよびnetworkに依存します(./libs/graphおよび./libs/networkのサブモジュール)

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

再帰的な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/

coreは、studioプロジェクトで2回複製されていることに注意してください。このディスク領域の浪費とは別に、coreを2回ビルドしていて、coreの2つの異なるバージョンを取得する可能性があるため、ビルドシステムに問題があります。

質問

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

可能な解決策

ライブラリの依存関係がいくらか示唆されており(つまり、「バージョンXで動作することがわかっている」または「バージョンXのみが公式にサポートされている」という方法で)、依存する可能性のあるアプリケーションまたはライブラリが、好きなバージョンでのビルドを担当している場合、次のシナリオを想像できます。

  • graphnetworkのビルドシステムに、coreの場所を(コンパイラのインクルードパスなどを使用して)どこにあるかを伝えます。 「スタンドアロン」と「依存関係」の2つのビルドターゲットを定義します。「スタンドアロン」は「依存関係」に基づいており、ローカルのcoreサブモジュールを指すインクルードパスを追加します。
  • 追加の依存関係を導入します:studioに対するcore。次に、studiocoreをビルドし、インクルードパスをcoreサブモジュールの独自のコピーに設定してから、graphおよびnetworkを「依存関係」モードでビルドします。

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

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の互換バージョンを取得する必要がある場合もありますすべてのプロジェクトで)。

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

50
André Caron

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

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

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

buildgraph/graph
buildgraph/core

そしてスタジオのプロジェクトは次のようになります:

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

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

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

5
chadsgilbert

graphnetworkの両方のサブモジュールをstudioに統合する場合、履歴の特定の時点で常に同じバージョンのcoreが必要です/ studiostudio/libs/coreサブモジュールをstudio/libs/{graph,network}/libsにsimlinkします。

更新:

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

./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は、coreの2つの異なるバージョンです。 graphはバージョン2を処理しますが、networkは作業が必要でバージョン1のままです。studioでは、coreのローカル埋め込みバージョンはどちらもv1を指します。実用的なプログラムを作るために。さて、ビルドの観点とは別に、すべてがサブモジュールでうまく機能します。

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

./studio/libs/network/libs/core

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

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

私はこの変更をローカルでコミットし、core内にstudioの2つの異なるバージョンを作成する機能を失いますが、coreをビルドするのは1回だけです。 v2にアップグレードする準備ができたら、次のことができます。

 git submodule update # (--rebase ?)

... studio/libs/network内。

1
coredump

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

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

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

基本的に、私は次のようなフォルダ構造を持っています:

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


e.g. ext/boost, ext/cppunit

これはディスクスペースの観点からはあまりいいとは言えませんが、レポがはるかに利用可能である限り、記録されたすべての状態をチェックアウトできることを保証します。

さらに、説明されているように、サブモジュールには多数の問題があります here

0
Wilbert

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

0
errordeveloper

ここでまったく同じ問題に直面しています。解決策の1つは、サブモジュールとしてlibscorenetworkを保持するいくつかのリポジトリgraphと、各ライブラリを通知するCMakeListsを用意することです。依存関係を見つける場所。各アプリケーションは、サブモジュールとしてlibsを持ち、必要なライブラリのみを使用します。

各libのテストは、2つの方法で設定できます。

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