Comment gérer les conflits avec les sous-modules git?

128

J'ai un superprojet git qui fait référence à plusieurs sous-modules et j'essaye de verrouiller un flux de travail pour le reste des membres de mon projet.

Pour cette question, disons que mon superprojet est appelé superyet que le sous-module est appelé subby. (Ensuite, c'est une simplification de ce que j'essaie de faire ... Je n'utilise pas réellement les branches pour les versions, mais j'ai pensé que ce serait plus facile de poser une question.)

Ma branche principale de superya la balise v1.0du projet git subbyréférencée en tant que sous-module. La branche de superyappelé one.oneet a changé la référence du sous-module pour pointer vers la balise v1.1de subby.

Je peux travailler dans chacune de ces branches sans accroc, mais si j'essaie de mettre à jour la one.onebranche avec des modifications de la masterbranche, je reçois des conflits et je ne sais pas comment les résoudre.

Fondamentalement, après avoir exécuté un git pull . mastercertain temps dans la subbybranche, il semble que cela crée des sous-modules supplémentaires.

Avant le pull / merge, j'obtiens la réponse souhaitée git submodulede la one.onebranche:

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

Mais après l'extraction, il ajoute des sous-modules supplémentaires lorsque je lance 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)

Comment supprimer / ignorer les références de sous-modules indésirables et valider mes conflits et modifications? Ou y a-t-il un paramètre que je peux utiliser avec mon original git pullqui ignorera mes sous-modules?

Tyler
la source

Réponses:

23

Je n'ai jamais vu cette erreur exacte auparavant. Mais j'ai une idée des problèmes que vous rencontrez. Cela ressemble à parce que les branches masteret one.onede superycontiennent des références différentes pour le subbysous - module, lorsque vous fusionnez des modifications de mastergit ne sait pas quelle référence - v1.0ou v1.1- doit être conservée et suivie par la one.onebranche de supery.

Si tel est le cas, vous devez sélectionner la référence souhaitée et valider cette modification pour résoudre le conflit. C'est exactement ce que vous faites avec la commande reset .

C'est un aspect délicat du suivi de différentes versions d'un sous-module dans différentes branches de votre projet. Mais le sous-module ref est comme n'importe quel autre composant de votre projet. Si les deux branches différentes continuent à suivre les mêmes références de sous-modules respectives après des fusions successives, alors git devrait être capable de travailler sur le modèle sans déclencher de conflits de fusion dans les futures fusions. D'un autre côté, si vous changez fréquemment de référence de sous-module, vous devrez peut-être supporter beaucoup de résolution de conflits.

Jesse Hallett
la source
1
Merci d'avoir éclairé la question. Cela a un sens pour moi maintenant et la commande de réinitialisation fonctionne parfaitement pour ma situation ci-dessus. Mais quelles seraient les commandes pour accepter le sous-module ref de la branche maître et jeter le ref dans le sous-module de la branche actuelle? Je sais comment gérer les conflits normaux, mais après trois jours à parcourir le Web, je ne trouve pas un exemple de code autre que rm -r. Et je commence à penser qu'il y a une raison pour que les exemples n'existent pas; les sous-modules sont si loin du superprojet que vous devez gérer chaque transition.
Tyler
26
ENFIN! Une réponse! J'avais added by us: ../Mono.Cecildans git statusmais git addet j'ai git rméchoué avec Mono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesparce que c'était juste un dossier vide et que git ne gère vraiment que les fichiers. git checkoutm'a donné Mono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updatedonné Skipping unmerged submodule Mono.Cecilet git checkout master Mono.Cecilfinalement réparé. Problème de base: la git statussuggestion est fausse, alors choisissez une branche et prenez sa copie du dossier avec checkout!
IBBoard
6
@ Commandement de IBBoard m'a aidé à cette situation - j'ai essayé git checkout --ours SUBMODet git add SUBMODet d' autres, mais finalement faisant , git checkout master SUBMODrésolu le conflit. Ce commentaire devrait probablement être une réponse, pas un commentaire ... :)
Colin D Bennett
90

Eh bien, il ne gère pas techniquement les conflits avec les sous-modules (c'est-à-dire: gardez ceci mais pas cela), mais j'ai trouvé un moyen de continuer à travailler ... et tout ce que j'avais à faire était de faire attention à ma git statussortie et de réinitialiser les sous-modules:

git reset HEAD subby
git commit

Cela réinitialiserait le sous-module à la validation de pré-extraction. Ce qui dans ce cas est exactement ce que je voulais. Et dans d'autres cas où j'ai besoin que les modifications soient appliquées au sous-module, je traiterai celles avec les flux de travail de sous-module standard (checkout master, déroulez la balise souhaitée, etc.).

Tyler
la source
Pour moi, cela semble seulement changer le statut du module en conflit de "les deux modifiés" à "supprimé".
Matt Zukowski le
4
Vous pouvez conserver le sous-module de la branche fusionnée à la place: git reset <merged-branch> subby
Edward Anderson
1
fonctionne pour moi comme prescrit dans la réponse .. git reset HEAD path / to / submodule / dir
estoy
56

J'ai eu un peu de mal avec les réponses à cette question et je n'ai pas eu beaucoup de chance avec les réponses dans un article similaire de SO . C'est donc ce qui a fonctionné pour moi - en gardant à l'esprit que dans mon cas, le sous-module était maintenu par une équipe différente, le conflit provenait donc de différentes versions de sous-module en master et de ma branche locale du projet sur lequel je travaillais:

  1. Exécuter git status- notez le dossier du sous-module avec des conflits
  2. Réinitialisez le sous-module à la dernière version validée dans la branche actuelle:

    git reset HEAD path/to/submodule

  3. À ce stade, vous disposez d'une version sans conflit de votre sous-module que vous pouvez maintenant mettre à jour vers la dernière version dans le référentiel du sous-module:

    chemin cd / vers / sous-module
    git submodule foreach git pull origin SUBMODULE-BRANCH-NAME
  4. Et maintenant vous pouvez commitcela et retourner au travail.

Emma Burrows
la source
16

Tout d'abord, recherchez le hachage que vous souhaitez référencer dans votre sous-module. puis courir

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

cela a fonctionné pour moi pour obtenir mon sous-module à la référence de hachage correcte et continuer mon travail sans avoir d'autres conflits.

hellatan
la source
1
ou vous pouvez simplement faire une commande git --theirs (ou --ours) subby
Bachi
@Bachi: git checkout --theirs et --ours n'a aucun effet sur les sous-modules.
Edward Anderson
1
Bien que cela résout le conflit, il n'est pas facile de déterminer <hashpointerhere>. Je ne connais pas de moyen facile de voir le commit de sous-module extrait de chaque côté du conflit. Quel que soit le commit que vous extrayez dans subby, il peut être différent de chaque côté de la fusion, ce qui n'est pas approprié dans un commit de fusion.
Edward Anderson
@nilbus c'est vrai. Nous avons abandonné le travail avec les sous-modules git car c'était l'une de nos préoccupations et il était très difficile de dire quel commit vous vouliez réellement. Nous avons utilisé composer (php) comme gestionnaire de paquets, ce que j'aime vraiment car il crée un fichier de verrouillage verrouillant les dépôts sur un certain hachage. Cependant, puisque nous utilisons node_modules dans plusieurs dépôts, nous rencontrerions des modules en conflit ici et là. Depuis, nous sommes passés à npm pour gérer ce genre de choses, mais c'est aussi une toute autre boîte de vers.
hellatan le
12

J'ai eu ce problème avec git rebase -i origin/masterune succursale. Je voulais prendre la version maître du sous-module ref, alors j'ai simplement fait:

git reset master path/to/submodule

puis

git rebase --continue

Cela a résolu le problème pour moi.

marathon
la source
3
Cela a fonctionné pour moi. Je suis toujours en train de comprendre ce qu'ils ont fait pour endommager le sous
Checo R
3

J'ai obtenu de l'aide de cette discussion. Dans mon cas, le

git reset HEAD subby
git commit

a travaillé pour moi :)

Mithun Das
la source
2

Eh bien, dans mon répertoire parent, je vois:

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

Alors je viens de faire ça

git reset HEAD linux
Kjeld Flarup
la source