2015-12-08 10 views
7

私はしばらくの間探していましたが、答えを見つけられませんでした(私は見た目がわからないかもしれません)。複数のリポジトリと1つのサブモジュール

私たちはリポジトリである自己リポジトリ(Libと呼ぶ)を持っています。リポジトリにはモジュールとサブモジュールのほとんどが含まれています。 2GBのサイズを持っているとしましょう...

ここでは、ProjA、ProjB、ProjCなどのプロジェクトが多数あります。それぞれ1つのサブモジュールとしてLibを使用しています。

ProjA

  • のLib(ブランチ:マスター、#コミット:1)

ProjB

  • のLib(ブランチ:他、#コミット:2)

ProjA

  • のLib(ブランチ:マスターは、#をコミット:4)

だから私は、ライブラリ(別名サブモジュール)のバージョンを修正するために参照するすべてのプロジェクトを維持することができるよながら。私は今、3 * 2GB = 6GBの同じサブモジュールを手に入れました。

正しいファイル/バージョン管理を維持しながら、1つのサブモジュールを参照する方法はありますか?

例:

ProjA

  • のLib/base_lib.h(v1.0の)

  • のLib/file_only_in_this_commit

ProjB

  • のLib/base_l ib.h(v1.0を)

ProjC

  • のLib/base_lib.h(V1.1)

ありがとう!

+0

わかりません。リポジトリごとに、サブモジュール内の1つのSHAへの参照しか持たないため、3回追加した理由があります。 'ProjA'、' ProjB'、 'ProjC'はすべて関連して相互作用するので、あなたはこの設定をしていると思いますか?それ以外の場合、これは3つの異なるリポジトリになる可能性があります。または、1つのリポジトリに3つのブランチを持つことができます。その場合は、サブモジュールの1つのバージョンだけを使用して、各ブランチで異なるサブモジュール参照を持つことができます。 – houtanb

+0

初期チェックアウト後にオブジェクトディレクトリを置き換えるハードリンクされたクローン – basin

+0

@basin gitでこのようなハードリンクを定義する方法はありますか?あなたの提案を手動で行うことは実際には問題を解決するものではなく、できるだけスクリプトを避けることを好むでしょう。 – Danra

答えて

3

内部的にはサブモジュール全体が非常にシンプルなので、あなたの好みに合わせてマスターすることができます。それぞれの内部

あなたProj<N>/.git/modules/Lib.urlProj<N> /.gitmodulesで指定されたリモート参照からクローン化された裸のリポジトリとLibサブモジュールに対応するフォルダがあります。それらの裸のリポジトリは最適化のポイントです。

可能であれば、ハードリンクを使用して簡単に再作成することができます。

1)あなたのすべてのprojのレポと同じファイルシステム上のフォルダにLibの裸のクローンを作成します。

git clone --bare url://to/Lib /path/to/Lib.git 

2)は、Pから裸のレポを参照し、レポでデフォルトのサブモジュールのレポを交換してください。 1:

cp ProjA/.git/modules/Lib.old/config ProjA/.git/modules/Lib/config 

mv ProjA/.git/modules/Lib ProjA/.git/modules/Lib.old // preserve it for a while 
git clone --bare --local url://to/Lib \ 
    --reference /path/to/Lib.git ProjA/.git/modules/Lib 

3)ProjA/.git/modules/Libに保存リポジトリから設定を復元します

すべてがProjAで動作しているかどうかを確認し、ProjA/.git/modules/Lib.oldなどを削除してもかまいません。この場合、すべてのreposは同じファイルオブジェクトを使用します。

gitでは、サブモジュールの特定の状態が正確なSHA1によって参照されます。 Libメインリポジトリ(例えばgit filter-branchなどの操作やコミットの削除につながる可能性のある操作)を実行しない限り、Libのすべての適切なコミットは永遠に保持されます。あなたのProj<N>は、特に完全に独立してコミットするので、の状態がProjALibProjBという別の状態を妨げる可能性があります。

6

を使用できProjA、ProjB内部の場所で、Libのサブモジュールのための追加worktreesを作成する(gitの2.5以降で利用可能)git worktreeなど

git worktreeが同じで数worktreesを作るために痛みますので、問題を回避し、サブモジュールの代わりに追加のワークツリーを作成し、それを正しいサブモジュールコミットに設定して、サブモジュール内のすべてのサブモジュールに対して再帰的に行うスクリプト(share_submodules)を作成しました。共有モジュール。

サブモジュールがgit submodule update --init --recursiveで作成されている場合と同じように動作するはずですが、すべてのコピーが1つのモジュールのオブジェクトを参照します。

サブモジュールを削除して移行する場合は、.gitにサブモジュールファイルがありますが、それを削除するにはfind_stray_submodules.pyを作成しました。

+0

この場合、 'git submodule'を使用することを完全にやめる必要があります、彼らはしないでしょうか? – user3159253

+0

@ user3159253:これは** git submoduleと互換性があります。私は、このソリューションをしばらく使ってから高い信頼度でしか言えませんでしたが(私は始めました) – yairchu

関連する問題