web-dev-qa-db-ja.com

サブモジュールのリモートとブランチを再作成するために `git clone --recursive`を取得するにはどうすればよいですか?

いくつかのサブモジュールを持つプロジェクトがあります。それらの多くは、カスタムmodのブランチを追加したGitHubフォークから複製されています。一般的な設定は次のようになります。

ローカルフォルダー内:MyProject1/Frameworks/SomeAmazingRepo /

$ git branch -vva
*my-fork                       123456 [my-fork/my-fork] Latest commit msg from fork
master                         abcdef [Origin/master] Latest commit msg from original repo
remotes/my-fork/my-fork        123456 [my-fork/my-fork] Latest commit msg from fork
remotes/my-fork/master         abcdef [Origin/master] Latest commit msg from original repo
remotes/Origin/HEAD            -> Origin/master
remotes/Origin/master          abcdef [Origin/master] Latest commit msg from original repo

$ git remote -v
my-fork                        [email protected]:MyUser/SomeAmazingRepo.git (fetch)
my-fork                        [email protected]:MyUser/SomeAmazingRepo.git (Push)
Origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (fetch)
Origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (Push)

git clone --recursive私のプロジェクトは新しいスピンオフプロジェクトを開始し、それが再発し始めると、これらのリポジトリの保存されたコミットが見つからないと主張するエラーを吐き出します。検査の結果、リモートが追加されておらず、ブランチがマスターに残っている(空の)ようです...

ローカルフォルダー内:MyProject2/Frameworks/SomeAmazingRepo /

$ git branch -vva
*master                        abcdef [Origin/master] Latest commit msg from original repo
remotes/Origin/HEAD            -> Origin/master
remotes/Origin/master          abcdef [Origin/master] Latest commit msg from original repo

$ git remote -v
Origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (fetch)
Origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (Push)

唯一の解決策は、リモートをすべてのリポジトリに手動で追加することです(非常に面倒です)。

上記のように追跡ブランチが2つあるが、リモートが1つしかない場合(Origin => my github fork)にも同様の問題があります。このような場合、コミットを見つけてチェックアウトしますが、トラッキングブランチの再作成に失敗し、「ぶら下がっている」コミットが残ります...警告が表示されないため、非常に怖いです。

サブモジュールのリモートとブランチを確実に再作成するために、プロジェクトのクローンを作成するにはどうすればよいですか?

16

git clone --recursivegit submodule update --init --recursiveと同等です。

そして git submodule update は記録されたSHA1(親リポジトリに記録された)のみをチェックアウトします:

登録されたサブモジュールを更新します。つまり、欠落しているサブモジュールのクローンを作成し、含まれているリポジトリのインデックスで指定されたコミットをチェックアウトします。
これにより、サブモジュールHEADが切り離されますになります。

2012:したがって、サブモジュールにアクティブなブランチが見つからないのが一般的です。
A git submodule foreach 'git checkout master'は、少なくともマスターブランチを設定できます(記録されたすべてのSHA1が各サブモジュールの「マスター」ブランチの一部であることが確実な場合。


2013-2014:サブモジュールでチェックアウトするブランチを指定するために.gitmodulesファイルを構成できます
特定のブランチからgitサブモジュールを更新するにはどうすればよいですか? "」を参照してください。

cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>

my-forkのように、サブモジュールにローカルで追加したリモートは、親リポジトリにまったく記録されません。
したがって、その親リポジトリのクローンを再度作成すると、.gitmodulesファイルに記録されているようにサブモジュールが初期化および更新されます( そのアドレスを変更 が可能ですが、oneは各サブモジュールに関連付けられています)。
各サブモジュールに関連付ける他のリモートアドレスがある場合は、プロセスを自動化するためのスクリプトが必要です。

サブモジュールの本質 」で説明されているように、サブモジュールは主に、履歴内の固定ポイントを記録/アクセスするために存在します。
サブモジュール内で直接開発できますが、そこに移動して適切なブランチを作成するか、適切なリモートを追加する必要があります。

これらのリポジトリの保存されたコミットが見つからないと主張するエラーを吐き出します。

サブモジュールでコミットするたびに、次のことを行う必要があります。

  • 関連するリモート(つまり、親リポジトリの.gitmodulesに記録されているリモート)にプッシュします。
  • 親リポジトリに戻り、その親をコミットします。

だが:

そのサブモジュールの関連するリモートリポジトリがnot 'my-fork'...であるときに' my-fork 'にプッシュした場合、次のクローンは'そのサブモジュールのコミットをチェックアウトすることはできません。


2014年8月の更新(Git 2.1)

commit 9393ae7 by Matthew Chen(charlesmchen :を参照してください。

サブモジュール:ドキュメント "sync --recursive"

git submodule sync」コマンドは--recursiveフラグをサポートしますが、ドキュメントにはこれについては記載されていません。
このフラグは、たとえば、サブモジュールのサブモジュールでリモートが変更された場合に役立ちます。


Git 2.23の更新(2019年第3四半期)

git clone --recurse-submodule --remote-submodules :gitlink親リポジトリSHA1の代わりに、トラッキングブランチですでにチェックアウトされているサブモジュールでクローンを作成することも検討できます。

25
VonC