Gitサブモジュールの更新


242

次の意味がわかりません(Gitサブモジュールの更新ドキュメントから)。

... --rebaseまたは--merge指定されていない限り、サブモジュールHEADがデタッチされます...

どのように--rebase/ --merge変更しますか?

私の主な使用例は、多数の中央リポジトリーを持つことです。サブリポジトリーを介して他のリポジトリーに組み込みます。これらの中央リポジトリを、元の場所で直接、または埋め込みリポジトリ(サブモジュールを介して使用するリポジトリ)内から改善できるようにしたいと思います。

  • これらのサブモジュール内から、通常のリポジトリと同じようにブランチ/変更を作成し、プッシュ/プルを使用できますか、または注意すべき点はありますか?
  • サブモジュールで参照されるコミットを(タグ付けされた)1.0から1.1に(元のリポジトリのヘッドがすでに2.0であっても)どのように進めるか、またはどのブランチのコミットを使用するかをどのように選択しますか?

「切り離されたヘッド」のトピックで、実用的な例については、stackoverflow.com / questions / 964876 / head - and -orighead-in- gitおよびstackoverflow.com/questions/237408/…も参照してください(サブモジュール関連ではありませんが、 )
VonC、2009

「メインプロジェクト内からサブモジュールの内容を変更することはできません」:はい、本当です。そして、私は自分の回答を編集して、その明らかな矛盾(変更不可能なサブモジュール、メインプロジェクトリポジトリからはまだ変更できる!)
VonCの2009

回答:


304

このGitProページは、gitサブモジュール更新の結果をうまくまとめています

を実行するgit submodule updateと、プロジェクトの特定のバージョンがチェックアウトされますが、ブランチ内はチェックアウトされません。これは、ヘッドが分離されていると呼ばれます—これは、HEADファイルがシンボリック参照ではなく、コミットを直接指すことを意味します。
問題は、変更が失われやすいため、分離したヘッド環境で作業したくないということです。
最初のサブモジュールの更新を行い、作業するブランチを作成せずにそのサブモジュールディレクトリにコミットし、その後コミットせずにスーパープロジェクトからgit submodule updateを再度実行すると、Gitは通知せずに変更を上書きします。技術的には作業を失うことはありませんが、それを指すブランチはないため、取得するのはやや困難になります。


2013年3月の注:

最新のgitサブモジュールの追跡」で説明したように、サブモジュール(git1.8.2)がブランチを追跡できるようになりました。

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 
# or (with rebase)
git submodule update --rebase --remote

git submodule update --remotevsgit pull」を参照してください。

MindTooth回答は、手動更新(ローカル構成なし)を示しています。

git submodule -q foreach git pull -q origin master

どちらの場合も、サブモジュール参照(gitlink親リポジトリインデックスの特別なエントリ)が変更され、メインリポジトリからの参照を追加、コミット、プッシュする必要があります。
次回、その親リポジトリのクローンを作成するときに、サブモジュールにデータが入力され、それらの新しいSHA1参照が反映されます。

この回答の残りの部分では、古典的なサブモジュール機能について説明します(サブモジュールの概念の背後にあるすべてのポイントである固定コミットへの参照)。


この問題を回避するには、git checkout -b workまたは同等のものを使用してサブモジュールディレクトリで作業するときにブランチを作成します。サブモジュールの更新を2回行っても、作業は元に戻りますが、少なくとも戻るためのポインターがあります。

サブモジュールを含むブランチを切り替えるのも難しい場合があります。新しいブランチを作成し、そこにサブモジュールを追加してから、そのサブモジュールのないブランチに切り替えても、サブモジュールディレクトリは追跡されていないディレクトリのままです。


だから、あなたの質問に答えるには:

通常のリポジトリの場合と同じように、ブランチ/モディフィケーションを作成してプッシュ/プルを使用できますか、または注意すべき点はありますか?

ブランチを作成して変更をプッシュできます。

警告(Gitサブモジュールチュートリアルから):サブモジュールの変更を、それを参照するスーパープロジェクトに発行(プッシュ)する前に、必ず発行(プッシュ)してください。サブモジュールの変更を公開するのを忘れると、他の人はリポジトリを複製できなくなります。

サブモジュールを参照するコミットを言う(タグ付き)1.0から1.1にどのように進めますか(元のレポのヘッドはすでに2.0ですが)

「サブモジュールを理解する」ページが役立ちます

Gitサブモジュールは、2つの可動部分を使用して実装されます。

  • .gitmodulesファイルと
  • 特別な種類のツリーオブジェクト。

これらは一緒に、プロジェクトの特定の場所にチェックアウトされている特定のリポジトリの特定のリビジョンを三角測量します。


gitのサブモジュールのページ

メインプロジェクト内からサブモジュールの内容を変更することはできません

100%正解:サブモジュールを変更することはできません。そのコミットの1つのみを参照してください。

このため、メインプロジェクト内からサブモジュールを変更すると、次のようになります。

  • サブモジュールで(上流モジュールに)コミットしてプッシュする必要がある。
  • 次に、メインプロジェクトに移動し、再コミットします(そのメインプロジェクトが、作成してプッシュした新しいサブモジュールコミットを参照するようにするため)。

サブモジュールを使用すると、コンポーネントベースのアプローチを開発できます。 メインプロジェクトは、他のコンポーネント(ここでは「サブモジュールとして宣言された他のGitリポジトリ」)の特定のコミットのみを参照します。

サブモジュールは、メインのプロジェクト開発サイクルに拘束されない別のGitリポジトリーへのマーカー(コミット)です。それは(「他の」Gitリポジトリ)独立して展開できます。
必要なコミットを他のリポジトリから選択するのはメインプロジェクトの責任です。

ただし、便宜上、これらのサブモジュールの1つをメインプロジェクトから直接変更する場合、Gitを使用すると、最初にそれらのサブモジュールの変更を元のGitリポジトリに公開し、次にメインプロジェクトを参照してコミットすることができます。新しい言ったサブモジュールのバージョン。

ただし、主な考え方は変わりません。次のような特定のコンポーネントを参照します。

  • 独自のライフサイクルを持っている
  • 独自のタグセットがある
  • 独自の開発をしています

メインプロジェクトで参照している特定のコミットのリストは、構成を定義します(これは、構成管理のすべてのことであり、単なるバージョン管理システムを展開します

コンポーネントがメインプロジェクトと同時に実際に開発される可能性がある場合(メインプロジェクトの変更にはサブディレクトリの変更が含まれるため、その逆も同様です)、コンポーネントは「サブモジュール」ではなくなりますが、サブツリーマージ(質問「レガシーコードベースをcvsから分散リポジトリに転送する」でも提示)、2つのGitリポジトリの履歴をリンクします。

Gitサブモジュールの本質を理解するのに役立ちますか?


77
ワオ。主に単純なものに対するその長い説明は、初心者がsvn:externalsだけにこだわるのを怖がらせるのに十分なはずです。;-)
2010年

2
@conny:しかし、「gitサブモジュールがsvn externalsと互換性がないのはなぜですか?」で詳しく説明しているように、サブモジュールは根本的に異なり、と互換性がありませんsvn:externals
VonC、2011年

1
申し訳ありませんが、私の質問に答えるために、私はサブモジュールにcdして、shaをgit checkoutするか、git pull / fetchで問題ありません。次に、ローカルリポジトリで更新をコミットします。
Henrik

2
@hced:次のコマンドを使用して、すべてのサブモジュールを一度にヒットすることもできますgit submodule foreach
Dav Clark

1
..それでもまだ取得できません。どこかにウェブ上で簡単な説明がありますか?
ユージーン2013年

135

各サブモジュールを更新するには、次のコマンドを(リポジトリのルートで)呼び出すことができます。

git submodule -q foreach git pull -q origin master

-qオプションを削除して、プロセス全体をたどることができます。


15
git submodule update --init --recursiveルートから実行すると、すべてが再帰的に取得され、初期化されていない場合は初期化されます。
Sam Soffes 2013年

10
@SamSoffesそれはまったく異なる目的を果たします。サブモジュールを更新すると、現在指しているコミット(必ずしも最新のコミットではない)でサブモジュールがチェックアウトされます。上記の回答のソリューションは、各サブモジュールのコミットをorigin / masterから最新のHEADに更新します。
indragie 2013年

7
私の新しい方法:git submodule update --rebase --remote
MindTooth、2015

19

--rebasevs. --mergeオプションに対処するには:

スーパーリポジトリAとサブモジュールBがあり、サブモジュールBでいくつかの作業を行いたいとしましょう。宿題を完了し、

git submodule update

あなたはHEADなしの状態にあるため、この時点で行うコミットは元に戻すのが困難です。したがって、サブモジュールBの新しいブランチで作業を開始しました

cd B
git checkout -b bestIdeaForBEver
<do work>

その間、プロジェクトAの他の誰かが、Bの最新かつ最高のバージョンが本当にAに値するものであると決定しました。習慣から、最新の変更をマージして、サブモジュールを更新します。

<in A>
git merge develop
git submodule update

ああ!おそらく、BがBの新しいチップに関連付けられたSHAを指しているか、または他のコミットを行っているため、ヘッドレス状態に戻ります。あなたが持っていれば:

git merge develop
git submodule update --rebase

Fast-forwarded bestIdeaForBEver to b798edfdsf1191f8b140ea325685c4da19a9d437.
Submodule path 'B': rebased into 'b798ecsdf71191f8b140ea325685c4da19a9d437'

これで、Bのこれまでで最高のアイデアが新しいコミットに基づいてリベースされました。さらに重要なのは、ヘッドレスな状態ではなく、まだBの開発ブランチにいるということです。

--merge変更をafterUpdateSHAにリベースするのではなく、beforeUpdateSHAからafterUpdateSHAへの変更を作業ブランチにマージします。)


7

Git 1.8.2には、--remoteこの動作を正確に可能にする新しいオプションが備わっています。ランニング

git submodule update --rebase --remote

各サブモジュールのアップストリームから最新の変更をフェッチし、それらをリベースして、サブモジュールの最新リビジョンをチェックアウトします。ドキュメントプットそれ:

-リモート

このオプションはupdateコマンドでのみ有効です。スーパープロジェクトの記録されたSHA-1を使用してサブモジュールを更新する代わりに、サブモジュールのリモート追跡ブランチのステータスを使用します。

これはgit pull、各サブモジュールで実行することと同じです。これは、通常、まさにあなたが望むものです。

(これはこの回答からコピーされました。)


十分に確立された正しい回答のある古い質問に回答することにした場合、その日の後半に新しい回答を追加しても、クレジットを得られない可能性があります。特徴的な新しい情報がある場合、または他の回答がすべて間違っていると確信している場合は、必ず新しい回答を追加してください。ただし、「まだ別の回答」では、通常、質問されてからしばらくしてから同じ基本情報が提供されます。 tクレジットをたくさん稼ぎましょう。これが何をするのかについての説明はなく、外部ドキュメントへのリンクも(十分ではありません)。
Jonathan Leffler 2017

2
それは、ありません「また別の答え」NO、他の答えは、このコマンドを(私が間違っていることを証明)を持っています。他の回答はうまくいきませんでした。このコメントはうまくいきましたので、元の所有者にクレジットを与えながら回答として投稿することにしました。だから、あなたの反対票を削除することを検討してください。
Iulian Onofrei 2017

ありますコメントすることによりMindToothこれは、彼らが今何をすべきかであると言って2015年からは。あなたはこれが何をするかについては何も説明していません(ただし、MindToothについては触れていますが、それが何を意味するのかについての具体的な説明はありません。このコメントのように、URLを埋め込むと役立ちます)。なぜそれが良い考えなのかは言いません。注意点はありません。私の考えでは、解決策よりも多くの質問が出されるため、これは有用な回答ではありません。
Jonathan Leffler 2017

1
それによって、機能しない代わりに機能することを意味しました。信じてください、もしもっと多くの人がこの答えを見たとしたら、それはうまくいくので喜んでくれるでしょう。このような場合、ほとんどの人は、実装方法ではなく、gitサブモジュールを更新するコマンドを知りたいだけです。
Iulian Onofrei 2017

私はあなたが間違っていることを証明するために答えを編集しました、また、stackoverflow.com / questions / 1979167 / git-submodule-update / … !!!
Iulian Onofrei 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.