gitサブモジュールとの競合をどのように管理しますか?


127

いくつかのサブモジュールを参照するgitスーパープロジェクトがあり、私のプロジェクトメンバーの残りが内部で作業できるようにワークフローをロックしようとしています。

この質問について、私のスーパープロジェクトが呼び出さsuperyれ、サブモジュールがと呼ばれるとしましょうsubby。(それから私がやろうとしていることの簡略化です...実際にはバージョンにブランチを使用していませんが、質問としてレイアウトするのが最も簡単だと思いました。)

私のマスターブランチにsuperyは、サブv1.0プロジェクトsubbyとして参照されるgitプロジェクトのタグがあります。枝superyと呼ばれone.one、タグにポイントにサブモジュールの参照を変更v1.1しますsubby

これらの各ブランチ内で問題なく作業できone.oneますが、masterブランチからの変更でブランチを更新しようとすると、いくつかの競合が発生し、それらを解決する方法がありません。

基本的にブランチでgit pull . masterしばらく実行した後、subby追加のサブモジュールを作成するように見えます。

プル/マージの前に、ブランチgit submoduleから必要な応答を取得しますone.one

$ git checkout master
$ git submodule
qw3rty...321e subby (v1.0)
$ git checkout one.one
$ git submodule
asdfgh...456d subby (v1.1)

しかし、プルの後、実行すると追加のサブモジュールが追加されますgit submodule

$ git pull . master
Auto-merged schema
CONFLICT (submodule): Merge conflict in subby - needs qu3rty...321e
Automatic merge failed; fix conflicts and then commit the results.

$ git submodule
qw3rty...321e subby (v1.0)
asdfgh...456d subby (v1.1)
zxcvbn...7890 subby (v1.1~1)

不要なサブモジュール参照を削除/無視して、競合や変更をコミットするにはどうすればよいですか?またはgit pull、私のサブモジュールを無視するオリジナルで使用できるパラメーターはありますか?

回答:


23

これまでにその正確なエラーを見たことがありません。しかし、私はあなたが遭遇している問題について推測しています。の変更をマージするmasterと、とのone.oneブランチにサブモジュールのsupery異なる参照が含まれているため、subbymaster -どのREFを知らないgitのv1.0v1.1-によって保持され、追跡されなければならないone.oneの枝supery

その場合は、必要な参照を選択し、その変更をコミットして競合を解決する必要があります。これは、まさにあなたがリセットコマンドでやっていることです。

これは、プロジェクトのさまざまなブランチにあるサブモジュールのさまざまなバージョンを追跡する際のトリッキーな側面です。ただし、サブモジュールrefは、プロジェクトの他のコンポーネントと同じです。2つの異なるブランチが連続するマージの後も同じそれぞれのサブモジュール参照を追跡し続ける場合、gitは今後のマージでマージの競合を発生させることなくパターンを解決できるはずです。一方、スイッチサブモジュールが頻繁に参照する場合は、多くの競合解決に耐えなければならない場合があります。


1
質問に光を当ててくれてありがとう。これは今では完全に理にかなっており、リセットコマンドは上記の状況に完全に対応しています。しかし、マスターブランチからサブモジュールrefを受け入れ、現在のブランチのサブモジュールにrefを破棄するコマンドは何でしょうか?通常の競合を処理する方法を知っていますが、3日間Webを精査した後、rm -r以外のコード例を1つも見つけることができません。そして、私は例が存在しない理由があると考え始めています。これまでのところ、サブモジュールはスーパープロジェクトから抽象化されているため、すべての遷移を管理する必要があります。
タイラー

26
最後に!答え!私は持っていadded by us: ../Mono.Cecilましたgit statusgit add、それは単に空のフォルダーであり、gitが実際に処理するのはファイルのみgit rmであるMono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesため、失敗しました。git checkoutMono.Cecil: needs merge, error: you need to resolve your current index firstgit submodule update与え、与えSkipping unmerged submodule Mono.Cecil、そしてgit checkout master Mono.Cecil最終的にそれを修正しました。基本的な問題:git status提案が間違っているため、ブランチを選択し、フォルダのコピーをcheckout
IBBoard 2012

6
IBBoardのコマンドは、このような状況で私を助けた@ -私が試したgit checkout --ours SUBMODgit add SUBMODし、他の人が、最終的にはやってgit checkout master SUBMOD競合を修正しました。このコメントは、おそらくコメントではなく回答になるはずです... :)
Colin D Bennett

89

まあ、それは技術的にサブモジュールとの競合を管理していません(つまり、これを維持しますが、そうではありません)が、作業を続行する方法を見つけました...そして、私がしなければならないすべては、git status出力に注意を払い、サブモジュールをリセットすることでした:

git reset HEAD subby
git commit

これにより、サブモジュールがプル前のコミットにリセットされます。この場合、まさに私が欲しかったものです。また、サブモジュールに変更を適用する必要がある他のケースでは、標準のサブモジュールワークフロー(チェックアウトマスター、目的のタグのプルダウンなど)でそれらを処理します。


私にとっては、これは競合するモジュールのステータスを「両方変更」から「削除」に変更するようです。
Matt Zukowski、2011

4
代わりに、マージされたブランチのサブモジュールを保持したい場合があります:git reset <merged-branch> subby
Edward Anderson

1
答えで規定されているように私のために働きます
。git

56

私はこの質問の回答に少し苦労しましたが、同様のSO投稿の回答にもあまり運がありませんでした。これが私にとってうまくいったことです-私の場合、サブモジュールは別のチームによって維持されていたので、マスターとプロジェクトのローカルブランチの別のサブモジュールバージョンが原因で競合が発生したことを覚えておいてください:

  1. 実行git status-競合のあるサブモジュールフォルダーを書き留めます
  2. サブモジュールを現在のブランチで最後にコミットされたバージョンにリセットします。

    git reset HEAD path/to/submodule

  3. この時点で、サブモジュールの競合のないバージョンがあり、サブモジュールのリポジトリで最新バージョンに更新できます。

    cd path / to / submodule
    git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
  4. そして今、あなたはcommitそれをして仕事に戻ることができます。


16

まず、サブモジュールが参照するハッシュを見つけます。次に実行します

~/supery/subby $ git co hashpointerhere
~/supery/subby $ cd ../
~/supery $ git add subby
~/supery $ git commit -m 'updated subby reference'

それは私にとって私のサブモジュールを正しいハッシュ参照にして、さらに衝突することなく私の仕事を続けるのに役立ちました。


1
またはあなただけのgitのチェックアウト--theirs(または--ours)subby行うことができます
バチ

@Bachi:git checkout --theirsおよび--oursはサブモジュールに影響を与えません。
エドワードアンダーソン

1
これにより競合は解決されますが、<hashpointerhere>を特定するのは簡単ではありません。競合の両側でサブモジュールのコミットがチェックアウトされていることを確認する簡単な方法がわかりません。subbyでチェックアウトするコミットは、マージのどちらの側とも異なる場合があるため、マージコミットでは適切ではありません。
エドワードアンダーソン

確かに@nilbus。gitサブモジュールでの作業は放棄しました。これは、私たちが抱えていた懸念の1つであり、実際にどのコミットが必要かを判断するのが非常に難しくなったためです。パッケージマネージャーとしてcomposer(php)を使用しました。これは、リポジトリを特定のハッシュにロックするロックファイルを作成するので、実際に気に入っています。ただし、複数のリポジトリ内でnode_modulesを使用しているため、あちこちで競合するモジュールに遭遇します。それ以来、このような問題を管理するためにnpmに切り替えましたが、これは他のワームの缶詰でもあります。
hellatan 2015

12

私はgit rebase -i origin/master枝にこの問題がありました。私はサブモジュールrefのマスターバージョンを取得したかったので、次のようにしました。

git reset master path/to/submodule

その後

git rebase --continue

これで問題は解決しました。


3
これでうまくいきました。サブモジュールを損傷するために彼らが何をしたか私はまだ理解しています
Checo R


2

よく私の親ディレクトリで私は見る:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)

だから私はこれをやった

git reset HEAD linux
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.