web-dev-qa-db-ja.com

gitサブモジュールcommit / Push / pull

Gitサブモジュールを使用したいのですが。

プロジェクトに変更をプッシュするために必要な手順は次のとおりです。

  1. サブモジュールディレクトリから追加/コミット/プッシュ
  2. 親ディレクトリから追加/コミット/プッシュ

プロジェクトの変更をプルするために必要な手順。

  1. 親ディレクトリからのgitpull
  2. 親ディレクトリからのgitサブモジュールの更新

元のリポジトリからサブモジュールを更新する手順

  1. サブモジュールディレクトリからのgitpull

私が心配しているのは、次の抜粋です http://git-scm.com/book/en/Git-Tools-Submodules

問題は、変更が失われやすいため、通常、デタッチされたHEAD環境で作業したくないことです。最初のサブモジュール更新を行う場合は、作成せずにそのサブモジュールディレクトリでコミットします。ブランチで作業し、その間にコミットせずにスーパープロジェクトからgit submodule updateを再度実行します(?? update/commit/updateは変更を失います?)Gitは通知なしに変更を上書きします。技術的には作業内容が失われることはありませんが、それを指すブランチがないため、取得がやや困難になります。

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

サブモジュールを変更するつもりですが、混乱させたくありません。上記のドキュメントでは、変更が失われる可能性について簡単に説明していますが、何が失われるのかわかりません。

損失を防ぐために、上記にリストした以上の追加の手順を実行する必要があるのではないかと思います。特に何人かのチームメンバーがサブモジュールを変更しますが、混乱させないために何をする必要がありますか?

11
eugene

同様の問題を解決しようとしているVisualStudioソリューションの外部プロジェクトで作業している人としての私の経験をあなたと共有したいと思います。私はgitに比較的慣れていないので、建設的な批判があれば、それをいただければ幸いです。

Visual Studioを使用している場合、Git Source Control Provider拡張機能は無料です( http://visualstudiogallery.msdn.Microsoft.com/63a7e40d-4d71-4fbb-a23b-d262124b8f4c )、そして私がそれをテストしたとき、サブモジュールを再帰的にコミットするようでした。

ただし、自宅でVS Web Developer Expressを開発に使用しているので、拡張機能に依存したくありません(内部で何が起こっているのかを把握しておくことも良いと思います)。したがって、私はコマンドを理解することを余儀なくされました、そして私は以下にいくつかのメモを追加しました。

[〜#〜] notes [〜#〜]

まだ読んでいない場合は、 http://git-scm.com/book/en/Git-Tools-Submodules をよく読んでください。かなりの注意点がありますので、このページに戻って参照します。これを読まずにサブモジュールを操作しようとすると、すぐに頭痛の種になります。

私のアプローチはこのチュートリアルに従いますが、いくつかの追加機能があります: http://blog.endpoint.com/2010/04/git-submodule-workflow.html

スーパープロジェクトを初期化したら(例:git init && git remote add Origin ...)、次のようにサブモジュールの追加を開始します。

git submodule add git://github.com/you/extension1.git extension
git submodule init
git submodule update

.gitmodulesファイルがこの追加を反映していることを確認してください。

[submodule "extension1"]
        path = extension
        url = git://github.com/you/extension1.git

サブモジュールディレクトリ(つまり、cd extension)に切り替えます。実行:

git fetch #I use fetch here - maybe you can use pull?
git checkout -b somebranchname #See the Git-Tools-Submodules link above for an explanation of why you need to branch

ここでREADME.txtに変更を加えてコミットできるようにし(また、このコミットで行ったことの記録を残すため)、モジュールをコミットしてブランチを適用しました(まだサブモジュールディレクトリ内にあります)。

git add .
git commit -a -m "Branching for extension submodule"

次に、スーパープロジェクト(つまり、cd ..)に入ります。また、ここでコミットする必要があります(私が言及したgitサブモジュールページを見ると、これが必要な理由が説明されています):

git status #will show you that your submodule has been modified
git commit -a -m "Commiting submodule changes from superproject"

これで、必要に応じて、プロジェクトをそのように再帰的にプッシュできます。

git Push --recurse-submodules=on-demand

すべてのサブモジュールについて、上記の手順を1回実行する必要があります。

すべてのサブモジュールに対してこれを実行し、コミットしてプッシュする変更を加え始めたら、次を使用できます。

git submodule foreach 'git add .' #recursively add files in submodules

残念ながら、git-slave(誰か?)のようなものを使用せずに再帰的にコミットする方法が見つからなかったので、各サブモジュールディレクトリに移動して、追加したファイルに対して通常のコミットを実行する必要があります。スーパープロジェクトでは:

git status #tells you that `extension` submodule has been modified
cd extension
git commit -a -m "Commiting extension changes in superproject edit session"

サブモジュールがコミットしたら、スーパープロジェクトもコミットする必要があります(再度)。

cd ..
git add .
git commit -a -m "Altered extension submodule"
git status #should now show 'working directory clean', otherwise commit other submodules in the same manner

これは少し面倒になる可能性がありますが(2回コミットすることになるため)、一度気付いたら、実際にはそれほど悪くはありません(各プロジェクトでコミットしている内容を確認する必要があるため)。私の意見ですが、スーパープロジェクトの機能の一部をサブモジュールに分離した場合、それはとにかく残りのプロジェクトから分離して機能するはずです(したがって、煩わしいときに異なる時間にコミットすることは世界の終わりではありません)。

今、私たちはもう一度プッシュすることができます...

git Push --recurse-submodules=on-demand

その後、サブモジュールに移動してもう一度プッシュを試みると、最新のコミットがすでにプッシュされているため、サブモジュールは何も実行しないことがわかります。

スーパープロジェクトのクローン作成(またはリモートOriginの使用)も非常に混乱する可能性があります。たとえば、git submodule updateの後にgit submodule initを2回実行する必要があります。 http://git-scm.com/book/en/Git-Tools-Submodules の「サブモジュールを使用したプロジェクトのクローン作成」セクションをお読みください。

スーパープロジェクトのクローンを作成するときに気になったのは、サブモジュールの最新の変更を取得することでした。 すべてのサブモジュールの最新を簡単にプルする を参照してください

これの私の変形は、チェックアウトされたサブモジュールに「開発」ブランチを使用し(ただし、好きなように呼び出すことができます)、スーパープロジェクトでこれを使用することです。

git submodule foreach git pull Origin development

これを設定すると、次のように、チェックアウトされたサブモジュールで変更をプッシュしたいブランチにもスワップします。

cd extension
git checkout -b development #This will tell you this is a new branch, but I believe this means a new branch of the local git repository - this will get pushed to the 'development' branch
#Make your changes, commit etc.

上記の手順を実行すると、クローン/リモートオリジンプロジェクトのサブモジュールへの変更(プッシュされた場合)が同じプロジェクトの他のクローン/リモートオリジンに表示されたことを確認できます(最後のサブモジュールプルコマンドを忘れないでください)。

それがお役に立てば幸いです。

20
Aaron Newton