25

私はGitにいくつかのサブモジュールを持つプロジェクトを持っています.メインプロジェクトを使用するには、それらのサブモジュールをダウンロードしてファイルを利用できるようにする必要があります.サブモジュールを機能させるには、独自のサブモジュールを利用できるようにする必要があります.これを設定するために、 を使用してサブモジュールを再帰的に初期化しgit submodule update --init --recursiveます。

ただし、サブモジュールの多くが依存関係を共有していることに気付きました。これは、疑似コードで次のようになっています (サブモジュールalpha -> betaを持つことを表します) 。alphabeta

my project -> submodule a -> submodule m
           -> submodule b -> submodule m
                          -> submodule n -> submodule x
           -> submodule c -> submodule x

私の質問は、各サブモジュールのファイル (少なくとも 1 つのコピー) を保持しながら、git のみを使用してこの重複を回避する方法はありますか?

シンボリックリンクを使用した解決策を想像することはできますが、git がこれを処理してくれるのが望ましいです。自分でシンボリックリンクを挿入すると、サブモジュールを更新するときに問題が発生するかどうかはわかりません。

理想的には、次のように単純化したいと思います。

my project -> submodule a -> symlink(submodule m)
           -> submodule b -> symlink(submodule m)
                          -> symlink(submodule n)
           -> submodule c -> symlink(submodule x)
           -> submodule m
           -> submodule n -> symlink(submodule x)
           -> submodule x

提案をお寄せいただきありがとうございます。

4

2 に答える 2

9

これはgitには組み込まれていませんが、あなたが言うようにシンボリックリンクで間違いなく実行できます。git new-workdir基本的にこれを行う (git の contrib ディレクトリから) を参照してください。サブモジュールとは何の関係も認識していませんが、サブモジュールはそれがサブモジュールであることを認識していません-そのことを知っているのは親リポジトリです。私はこれを試したことはありませんが、次のように使用できると確信しています。

# remove the target first (new-workdir will refuse to overwrite)
rm -rf submodule_b/submodule_m

#               (original repo)         (symlinked repo)
git new-workdir submodule_a/submodule_m submodule_b/submodule_m

基本的にすべての .git ディレクトリをシンボリックリンクすることで機能します。シンボリックリンクされていない注目すべき点は次のとおりですHEAD。2 つのディレクトリは異なるものをチェックアウトできますが、同じ参照とオブジェクトを共有します。

ここからはうまくいくはずです。スーパーモジュールでコマンドを実行するgit submoduleと、サブモジュールに入り、そこで適切なコマンドが実行されます。これらはすべて期待どおりに機能します。

このようなシンボリックリンクされたリポジトリで通常注意する必要があるのは、それらが同じブランチのセットを共有しているため、両方が同じブランチをチェックアウトしていて、一方にコミットすると、もう一方がアウトになることです。同期します。ただし、サブモジュールでは、介入しない限り、基本的に常に切り離された HEAD 状態であるため、これは一般的に問題にはなりません。

于 2010-11-07T03:04:40.780 に答える
4

git-new-workdirここで説明されているように、良い解決策ではないかもしれません: http://comments.gmane.org/gmane.comp.version-control.git/196019

git 1.7.10 ではうまくいきませんでした。

ハードリンクを使用してユースケースを解決しました。OS X を実行しており、ファイルシステムでディレクトリへのハードリンクを作成できます: https://github.com/darwin/hlink

これで、サブモジュールのディレクトリをハードリンクすることができ、git はそれらを透過的に扱います。ハード リンクには、HEAD を含むすべてのサブモジュールが完全にミラーリングされるという優れた特性もあります。これは、私の場合に好む動作です。

OK、アイデアは、1 つの「マスター」サブモジュール リポジトリを作成し、すべての「スレーブ」コピーをそこにハードリンクすることです。これにより、それらすべてが互いに区別できなくなり、完全に同期されます。

警告:

1) .git の相対パスが機能する限り、これは正常に機能します。つまり、ディレクトリ ツリーの同じディレクトリ レベルにあるサブモジュールのみをハードリンクできます。これは私の場合でした。ハードリンクタスクで .gitfiles を変更することで簡単に修正できると思います。注: 以前のサブモジュールの .git は、別の場所を指しているプレーンテキストの .git ファイルではなく、自己完結型のディレクトリだったため、これは git 1.7.10 より前では問題になりません。

2) ハード リンクは、いくつかの非互換性をもたらす可能性があります。たとえば、TimeMachine はバージョン管理のために内部でハード リンクを使用するため、混乱します。TimeMachine からプロジェクト ディレクトリを必ず除外してください。

仕事をしている私のrakeタスクの例は次のとおりです :

于 2012-04-22T03:52:28.587 に答える