Wie gehe ich mit Konflikten mit Git-Submodulen um?

127

Ich habe ein Git-Superprojekt, das auf mehrere Submodule verweist, und ich versuche, einen Workflow zu sperren, damit der Rest meiner Projektmitglieder darin arbeiten kann.

Nehmen wir für diese Frage an, mein Superprojekt wird aufgerufen superyund das Submodul wird aufgerufen subby. (Dann ist eine Vereinfachung dessen, was ich versuche ... Ich verwende die Zweige nicht für Versionen, aber ich dachte, es wäre am einfachsten, sie als Frage zu formulieren.)

In meinem Hauptzweig von superywird das Tag v1.0des Git-Projekts subbyals Submodul bezeichnet. Der Zweig von hat die Referenz des Submoduls superyaufgerufen one.oneund geändert, um auf das Tag v1.1von zu verweisen subby.

Ich kann problemlos in jedem dieser Zweige arbeiten, aber wenn ich versuche, den one.oneZweig mit Änderungen aus dem masterZweig zu aktualisieren, erhalte ich einige Konflikte und weiß nicht, wie ich sie lösen kann.

Grundsätzlich sieht es nach einer git pull . masterWeile in der subbyVerzweigung so aus, als würden zusätzliche Submodule erstellt.

Vor dem Ziehen / Zusammenführen erhalte ich die gewünschte Antwort git submodulevon der one.oneVerzweigung:

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

Aber nach dem Ziehen werden zusätzliche Submodule hinzugefügt, wenn ich Folgendes ausführe 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)

Wie lösche / ignoriere ich die unerwünschten Submodulreferenzen und begebe meine Konflikte und Änderungen? Oder gibt es einen Parameter, den ich mit meinem Original verwenden git pullkann, der meine Submodule ignoriert?

Tyler
quelle

Antworten:

23

Ich habe diesen genauen Fehler noch nie gesehen. Aber ich habe eine Vermutung über die Schwierigkeiten, auf die Sie stoßen. Es sieht so aus, als ob die masterund one.one-Zweige von superyunterschiedliche Refs für das subbySubmodul enthalten. Wenn Sie Änderungen von mastergit zusammenführen, wissen Sie nicht, welche Ref - v1.0oder v1.1- vom one.oneZweig von beibehalten und verfolgt werden sollen supery.

Wenn dies der Fall ist, müssen Sie die gewünschte Referenz auswählen und diese Änderung festschreiben, um den Konflikt zu lösen. Welches ist genau das, was Sie mit dem Befehl reset tun .

Dies ist ein schwieriger Aspekt beim Verfolgen verschiedener Versionen eines Submoduls in verschiedenen Zweigen Ihres Projekts. Die Submodul-Referenz ist jedoch genau wie jede andere Komponente Ihres Projekts. Wenn die beiden verschiedenen Zweige nach aufeinanderfolgenden Zusammenführungen weiterhin dieselben Submodul-Refs verfolgen, sollte git in der Lage sein, das Muster zu erarbeiten, ohne bei zukünftigen Zusammenführungen Zusammenführungskonflikte auszulösen. Wenn Sie jedoch häufig das Submodul wechseln, müssen Sie möglicherweise eine Menge Konflikte lösen.

Jesse Hallett
quelle
1
Vielen Dank, dass Sie etwas Licht in die Frage gebracht haben. Das macht jetzt für mich total Sinn und der Reset-Befehl funktioniert perfekt für meine obige Situation. Aber was wären die Befehle, um die Referenz des Submoduls vom Hauptzweig zu akzeptieren und die Referenz in das Submodul des aktuellen Zweigs zu werfen? Ich weiß, wie man mit normalen Konflikten umgeht, aber nach drei Tagen im Internet kann ich kein anderes Codebeispiel als rm -r finden. Und ich fange an zu denken, dass es einen Grund dafür gibt, dass die Beispiele nicht existieren; Submodule sind so weit vom Superprojekt abstrahiert, dass Sie jeden Übergang verwalten müssen.
Tyler
26
ENDLICH! Eine Antwort! Ich hatte added by us: ../Mono.Cecilin git statusaber git addund git rmscheiterte mit, Mono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesweil es nur ein leerer Ordner war und Git nur wirklich Dateien handhabt. git checkoutgab mir Mono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updategab Skipping unmerged submodule Mono.Cecilund git checkout master Mono.Cecilreparierte es endlich. Grundproblem: Der git statusVorschlag ist falsch, wählen Sie also einen Zweig aus und nehmen Sie die Kopie des Ordners mit checkout!
IBBoard
6
@ IBBoard Befehl mich mit dieser Situation geholfen - ich versuchte , git checkout --ours SUBMODund git add SUBMODund andere, aber schließlich Tun git checkout master SUBMODden Konflikt festgelegt. Dieser Kommentar sollte wahrscheinlich eine Antwort sein, kein Kommentar ... :)
Colin D Bennett
89

Nun, es ist nicht technisch, Konflikte mit Submodulen zu verwalten (dh: dies behalten, aber nicht das), aber ich habe einen Weg gefunden, weiter zu arbeiten ... und alles, was ich tun musste, war auf meine git statusAusgabe zu achten und die Submodule zurückzusetzen:

git reset HEAD subby
git commit

Das würde das Submodul auf das Pre-Pull-Commit zurücksetzen. Was in diesem Fall genau das ist, was ich wollte. In anderen Fällen, in denen die Änderungen am Submodul vorgenommen werden müssen, werde ich diese mit den Standard-Submodul-Workflows (Checkout-Master, Herunterziehen des gewünschten Tags usw.) behandeln.

Tyler
quelle
Für mich scheint dies nur den Status des in Konflikt stehenden Moduls von "beide geändert" in "gelöscht" zu ändern.
Matt Zukowski
4
Vielleicht möchten Sie stattdessen das Submodul des zusammengeführten Zweigs behalten: git reset <merged-branch> subby
Edward Anderson
1
funktioniert für mich wie in der Antwort vorgeschrieben .. git reset HEAD path / to / submodule / dir
estoy
56

Ich hatte ein wenig Probleme mit den Antworten auf diese Frage und hatte auch nicht viel Glück mit den Antworten in einem ähnlichen SO-Beitrag . Das hat also für mich funktioniert - wenn man bedenkt, dass in meinem Fall das Submodul von einem anderen Team gewartet wurde, kam der Konflikt von verschiedenen Submodulversionen in Master und meinem lokalen Zweig des Projekts, an dem ich gearbeitet habe:

  1. Ausführen git status- Notieren Sie sich den Submodulordner mit Konflikten
  2. Setzen Sie das Submodul auf die Version zurück, die zuletzt im aktuellen Zweig festgeschrieben wurde:

    git reset HEAD path/to/submodule

  3. Zu diesem Zeitpunkt haben Sie eine konfliktfreie Version Ihres Submoduls, die Sie jetzt auf die neueste Version im Repository des Submoduls aktualisieren können:

    CD-Pfad / zu / Submodul
    Git-Submodul für jeden Git-Pull-Ursprung SUBMODULE-BRANCH-NAME
  4. Und jetzt können Sie commitdas und wieder an die Arbeit gehen.

Emma Burrows
quelle
16

Suchen Sie zunächst den Hash, auf den Ihr Submodul verweisen soll. dann renne

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

Das hat für mich funktioniert, um mein Submodul auf die richtige Hash-Referenz zu bringen und meine Arbeit fortzusetzen, ohne weitere Konflikte zu bekommen.

Hellatan
quelle
1
oder Sie könnten einfach eine Git-Kasse machen - ihre (oder - unsere) Subby
Bachi
@Bachi: git checkout --theirs and --ours hat keine Auswirkung auf Submodule.
Edward Anderson
1
Dies löst zwar den Konflikt, es ist jedoch nicht einfach, <hashpointerhere> zu bestimmen. Ich kenne keine einfache Möglichkeit, das Submodul-Commit auf jeder Seite des Konflikts zu überprüfen. Welches Commit Sie in Subby auschecken, kann sich von beiden Seiten der Zusammenführung unterscheiden, was bei einem Zusammenführungs-Commit nicht angemessen ist.
Edward Anderson
@nilbus das ist wahr. Wir haben die Arbeit mit Git-Submodulen aufgegeben, da dies eines der Probleme war, die wir hatten, und es sehr schwierig gemacht, zu sagen, welches Commit Sie tatsächlich wollten. Wir haben Composer (PHP) als Paketmanager verwendet, was mir eigentlich gefällt, da es eine Sperrdatei erstellt, die die Repos an einen bestimmten Hash sperrt. Da wir jedoch node_modules in mehreren Repos verwenden, stoßen wir hier und da auf widersprüchliche Module. Wir sind seitdem auf npm umgestiegen, um dieses Zeug zu verwalten, aber das ist auch eine ganz andere Dose Würmer.
Hellatan
12

Ich hatte dieses Problem mit git rebase -i origin/mastereiner Filiale. Ich wollte die Master-Version des Submoduls ref nehmen, also tat ich einfach:

git reset master path/to/submodule

und dann

git rebase --continue

Das hat das Problem für mich gelöst.

Marathon-
quelle
3
Das hat bei mir funktioniert. Ich überlege immer noch, was sie getan haben, um das Submodul zu beschädigen
Checo R
3

Ich habe Hilfe von dieser Diskussion bekommen. In meinem Fall die

git reset HEAD subby
git commit

hat für mich gearbeitet :)

Mithun Das
quelle
2

Nun, in meinem Elternverzeichnis sehe ich:

$ 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)

Also habe ich das einfach gemacht

git reset HEAD linux
Kjeld Flarup
quelle