5

私はmercurialリポジトリを持っており、gitサブレポ(hg 1.8)を問題なく追加しました。

問題は、この git サブレポの内部に別の git サブレポジトリがあり、git サブレポ.gitmodulesで a を実行しない限り、プルされていない (git のサブレポ ファイルにある) ことですgit clone --recursive: この方法で動作します。

問題:hg pull別のマシンのリポジトリでを実行するとgit subrepo、 がプルされますが、 はプルされません.gitmodules。.gitmodules は、.gitmodules を実行したときにのみ他のマシンに取り込まれましたgit clone --recursive

この状況を処理するための提案はありますか? 醜い解決策は、git cloneサブレポのように振る舞うことなく、すべてのファイル (git メタデータを含む) を mercurial リポジトリに単純に追加することです。

4

3 に答える 3

3

最善の修正は、MercurialのGitサブリポジトリサポートにパッチを適用して、常にGitの再帰オプションを使用することだと思います(たとえばgit clone --recursive、Gitベースのサブリポジトリのクローンを作成するときgit pull --recurse-submodules && git submodule update、更新されたGitベースのサブリポジトリをプルした後など)。Git開発者は、サポートしたいワークフローの1つが「サブモジュールを表示したくない」であるため、サブモジュールを自動的に初期化しないことを特に選択したことを知っていますが、「常にすべてのサブリポジトリを初期化する」の方が適している可能性があります。デフォルトのMercurialモードの操作(私はMercurialユーザーではないため、デフォルトのMercurialスタイルがどうなるかについてはよくわかりません)。


subrepo/.gitmodulesそれが発生するまで、エントリをエントリに変換することで問題を回避できる可能性があり.hgsubます。手動で行うのは簡単ですが、重要な場合はおそらく自動化できます(および/またはgit configからパスとURLを抽出するために使用します)。大幅に変更されるファイルを扱っている場合、これは魅力的ではない可能性があります(変更されるたびに同期することに非常に注意を払う必要があります)。.git/config.gitmodules.gitmodules.hgsub.gitmodules

私はこれを4つのリポジトリでテストしました。

  • gitsub —「リーフ」リポジトリ(Gitサブモジュールなし)
  • gitsuper —Gitの「スーパープロジェクト」。サブモジュールとしてのgitsub
    gitsub/です
  • hgsuper2 —水銀の「スーパープロジェクト」。サブリポジトリとしてのgitsuper、
    gitsuper/サブリポジトリとしてのgitsubです。
    gitsuper/gitsub
  • hgsuper2-clone —クローン化されたMercurialの「スーパープロジェクト」。サブリポジトリとしてのgitsuper、
    gitsuper/サブリポジトリとしてのgitsubです。
    gitsuper/gitsub

私はこれらを次のように構築してテストしました:

  1. gitsubを作成します。いくつかのコンテンツを追加してコミットします。
  2. gitsuperを作成します。
    1. コンテンツを追加します。
    2. git submodule add url-of-gitsub gitsub && git submodule init
    3. git commit -m 'added gitsub'
  3. hgsuper2を作成します。
    1. コンテンツを追加します。
    2. git clone --recursive url-of-gitsuper gitsuper
    3. echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
    4. echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub
      gitsuper/.git/configこれらの最後の2つのステップは、と のビットから自動化できますgitsuper/.gitmodules
    5. hg add .hgsub && hg commit -m 'added Git subrepositories'
  4. hgsuper2のクローンを作成します。hgsuper2からクローンを作成します。
    とで適切な内容を取得しgitsuper/ますgitsuper/gitsub/
  5. 新しいコンテンツを更新してgitsubにコミットします。
  6. gitsuperを更新します。
    1. 一部のコンテンツを追加または変更して、ステージングします。
    2. (cd gitsub && git pull origin master)
    3. git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
  7. hgsuper2で、Gitサプレポジトリから変更をプルします
    1. (cd gitsuper && git pull --recurse-submodules && git submodule update)
      のコンテンツはプルによって更新されますgitsuper/gitsuper/gitsub/
    2. hg commit -m 'updated gitsuper (and its contents)'
  8. hgsuper2-cloneにプルします。
    1. hg pull -u
      Gitのコンテンツが更新されました。

私のテストは(Mercurial1.8.1とGit1.7.4.1を使用して)機能しましたが、1つのバグに気づきました。Mercurialは、 (Gitがそのサブモジュールで行うように)切り離されたHEADを使用する代わりに、または単に(ie)を使用する代わりに、奇妙な名前のGitブランチを作成してチェックアウトします( origin/master(ie ))。また、時々少しくさびになり、次のようなエラーが発生するようです。refs/heads/origin/mastermasterrefs/heads/master

fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper

問題のGitリポジトリ(GitベースのMercurialサブリポジトリgit checkout HEAD~0 && git branch -D origin/master)に移動し、次のコマンドで削除できるように(最初はHEADをデタッチし、(さらに重要なことに)ブランチから移動して)ブランチを削除することで問題を回避しました)。この回避策は、Gitリポジトリにローカルの変更が変更されていない限り、完全に安全です。

git submodule initもう1つの小さな問題は、Mercurialによって作成されたGitスーパーリポジトリでGitサブモジュールコマンドを発行する前に、Gitにサブモジュールについて通知するために実行する必要があることです(サブモジュールは適切な場所に複製されましたが、Mercurialによって確立されたためです。にそれらのエントリはありません.git/config

同様に、GitベースのMercurialサブリポジトリ内からGitによって管理されるコンテンツへの変更をオーサリングする場合は、Mercurialでコミットする前に、常にGitサブモジュールを追加し、コミットし、Gitサブリポジトリからプッシュするように注意する必要があります。 「スーパープロジェクト」。そうしないと、Mercurialがgitsupergitsubの1つの組み合わせを使用し、gitsuper自体が別のバージョンのgitsubを参照するという状況に陥る可能性があります。つまり、Gitのサブモジュールコードをバイパスするため(GitサブモジュールをMercurialサブリポジトリとして管理することにより)、GitのサブモジュールのビューをMercurialのビューと同期させるように注意する必要があります。

于 2011-04-03T08:45:00.707 に答える
0

Git は実際にはサブプロジェクトを「好き」ではありません。少し調べてみましたが、探している情報がhttp://git.rsbx.net/Notes/Git_Subprojects.txtに含まれているようです。

于 2011-04-02T21:19:34.073 に答える