70

submoduleに配置したいくつかの共通コードを持つ2 つ以上のプロジェクト ( ProjectFooおよびProjectBarと呼びましょう) があります。

私の理解では、ProjectFoo内からサブモジュールへの変更をコミットすると、すべてのProjectFooクローンのみが表示できる切り離されたヘッドになります。

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(56f21fb0...) $ git push
Everything up-to-date

これはおそらく、masterブランチが変更されていないためです。私はおそらく次のようなことをすることができますgit checkout master && git merge Everything up-to-dateが、それはかなり醜いようです。同じことをgit reset --hard masterするかもしれませんが、それはさらに醜いようです。

プロジェクトで共通のコードを共有し、それを使用するプロジェクト内から更新するにはどうすればよいですか? つまり、そのサブモジュールにコミットすると、この同じサブモジュールを使用するさまざまなリポジトリ (クローンだけでなくリポジトリ) がすべて更新されます。

- - 編集 - -

明らかに、チェックアウトしたリポジトリがめちゃくちゃで壊れていました。そのように最初から正しく機能するはずです(この例ではProjectFooで):

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git commit -am "Common code fix."
(master) $ git push
....
   fbfdd71..0acce63  master -> master
(master) $ cd ..
(master) $ git add ProjectFooBarCommoneSubmodule
(master) $ git commit -m "Submodule update."

次に、 ProjectBarなどの他のプロジェクトからその変更を取得します。

(master) $ cd ProjectFooBarCommoneSubmodule/
(master) $ git pull

最新の共通コードに更新します。分離ヘッドの場合はAgit checkout masterが必要な場合があります。

4

6 に答える 6

77

簡潔な答え:

cd ProjectFooBarCommoneSubmodule
git checkout master
<Do your editing>
git commit --all -m "Lots of fixes"
git push submodule_origin master
cd ..

git add ProjectFooBarCommoneSubmodule
git commit -m "Bumped up the revision of ProjectFooBarCommoneSubmodule"
git push origin master

長い方:

Git サブモジュールは依存メカニズムであり、メイン プロジェクト (たとえば A) がサブプロジェクト (たとえば B) で指定されたリビジョンを定義し、それがプロジェクト A の構築に使用されます。ツールが有用であるためには、動作が予測可能でなければなりません。 Aさんの視点から。誰かが変更をプロジェクト A に組み込むことを決定しない限り、依存関係を変更することはできません。プロジェクト B の変更が自動的にインポートされた場合、あらゆる種類の厄介なことが発生する可能性があります。A はすぐに失敗に気付くため、コンパイル エラーがおそらく最良のものです。これが、B:の頭が切り離された状態に保たれている理由です。

B の状態は A に格納されており (チェックアウトgit submodule status)、有効にするためには、リビジョンの変更を A で実行してコミットする必要があります。これが上記の例で発生することです。A はリポジトリに保存されているリビジョン番号を変更し、バージョンを最新のものに上げます。このプロセスは他のメインリポジトリでも繰り返す必要があるため、自動の「マスターを使用」スイッチはありません。

ところで。サブモジュールに関するGit の本の章とサブモジュールのマニュアル ページには、通常の使用法や典型的な落とし穴など、サブモジュールに関する多くの有用な情報が含まれています。チェックアウトする価値があります。


編集:これをよりよく説明しようとします

私は自分の github アカウントで自由にサンプル プロジェクトを作成しました。コミットは意味がなく、ジャンクが含まれていますが、セットアップは問題ないはずです。フォローするのでチェックしてみてください。

ProjectFoo と ProjectBar は、共通のサブモジュールでコードを共有します。

ProjectFooBarCommoneSubmodule: マスターは6850e4e4c1fac49de398 です

ProjectFoo で:

git submodule status

-6850e4e4c1fac49de39890703f21486ca04b87a0共通

ProjectBar で:

git submodule status

-6850e4e4c1fac49de39890703f21486ca04b87a0共通

両方とも同じリビジョンを指していますよね?ここでのコツは、ProjectFoo と ProjectBarが同じものであるにもかかわらず、ブランチ (マスター) ではなくリビジョン(6850e4e4c1fac49de39890703f21486ca04b87a0)を指していることを確認することです。1 つはデタッチされたヘッドで、もう 1 つは名前付きブランチです。

ProjectFooBarCommoneSubmodule を修正したい場合は、たとえば ProjectFoo のサブディレクトリに移動し、リビジョンの代わりにブランチを選択できます

git checkout master 
<Do your coding and pushing here>

次に、1 つ上のディレクトリに移動し、git サブモジュールのステータスを確認します。それはあなたが今同期していないことをあなたに伝えるはずです. 例えば

git submodule status

+e24bd2bf45d52171a63b67ac05cd4be0ac965f60 共通 (heads/master-1-ge24bd2b)

これで、git add を実行して、この特定のコミット (ge24bd...) への参照を設定し、コミットを実行できます。その後、サブモジュールの参照は、たまたま ProjectFooBarCommoneSubmodule のマスターでもあるこのリビジョンを指しています。

ここで、ProjectBar の参照も更新する必要があります。ProjectBar/common に移動し、git fetch origin を実行します (これは早送りマージです)。

git checkout master 
cd ..
git add common
git commit -m "Bumped up the revision"
git push origin master # to publish the revision bump to everybody else

そのため、他の git リポジトリと同様に、切り離されたヘッドで作業する必要はありません。マスターで作業するか、名前付きブランチを作成できます。いずれにせよ、アップストリームに ProjectFooBarCommoneSubmodule の変更が含まれていることを確認してください。そうしないと、ProjectFoo と ProjectBar の両方が存在しないものを参照している場合に壊れてしまいます。これがそれをよりよく説明したことを願っています

于 2010-08-28T21:27:38.507 に答える
1

一度にすべてのサブモジュールをコミットしてプッシュしたい場合は、次のようにします。

git submodule foreach 'git commit -a' ;
git submodule foreach 'git push --all' ;
git commit -a && \
git push --all --recurse-submodules=on-demand
于 2016-11-03T13:09:36.233 に答える
0

デタッチされた HEAD から変更されたものをマスターにマージするには、次を実行します。

git rebase HEAD master

次に、マスターをチェックアウトします(-f強制的に使用):

git checkout master

git submodule foreach処理するサブモジュールが複数ある場合は、次を使用します。

git submodule foreach git pull origin master -r
于 2017-01-14T01:13:07.070 に答える