Come gestisco i conflitti con i sottomoduli git?


127

Ho un superprogetto git che fa riferimento a diversi sottomoduli e sto provando a bloccare un flusso di lavoro affinché gli altri membri del mio progetto lavorino all'interno.

Per questa domanda, supponiamo che il mio superprogetto venga chiamato superye venga chiamato il sottomodulo subby. (Quindi è una semplificazione di ciò che sto cercando di fare ... In realtà non sto usando i rami per le versioni, ma ho pensato che sarebbe stato più semplice fare una domanda.)

Il mio ramo principale di superyha il tag v1.0del progetto git subbyindicato come sottomodulo. Il ramo di superychiamato one.onee modificato il riferimento del sottomodulo in modo che punti al tag v1.1di subby.

Posso lavorare all'interno di ciascuno di questi rami senza intoppi, ma se provo ad aggiornare il one.oneramo con le modifiche dal masterramo ricevo alcuni conflitti e non riesco a risolverli.

Fondamentalmente dopo aver eseguito un git pull . masterpo 'di tempo nel subbyramo, sembra che crei sottomoduli aggiuntivi.

Prima del pull / merge, ottengo la risposta desiderata git submoduledal one.oneramo:

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

Ma dopo il pull, aggiunge ulteriori sottomoduli quando corro 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)

Come posso eliminare / ignorare i riferimenti al sottomodulo indesiderati e impegnare i miei conflitti e le mie modifiche? O c'è un parametro che posso usare con il mio originale git pullche ignorerà i miei sottomoduli?

Risposte:


23

Non ho mai visto quell'errore esatto prima. Ma ho un'idea del problema che stai riscontrando. Sembra che i rami mastere one.onedi superycontengano riferimenti diversi per il subbysottomodulo, quando unisci le modifiche a mastergit non sa quale ref - v1.0o v1.1- dovrebbe essere tenuto e tracciato dal one.oneramo di supery.

In tal caso, è necessario selezionare il riferimento desiderato e confermare la modifica per risolvere il conflitto. Che è esattamente quello che stai facendo con il comando reset .

Questo è un aspetto complicato del tracciamento di diverse versioni di un sottomodulo in diversi rami del progetto. Ma il riferimento al sottomodulo è proprio come qualsiasi altro componente del tuo progetto. Se i due diversi rami continuano a tenere traccia degli stessi rispettivi riferimenti del sottomodulo dopo successive fusioni, allora git dovrebbe essere in grado di elaborare il modello senza sollevare conflitti di fusione in future fusioni. D'altra parte, se si cambia frequentemente i riferimenti al sottomodulo, potrebbe essere necessario affrontare un sacco di risoluzione dei conflitti.


1
Grazie per aver fatto luce sulla domanda. Questo ha perfettamente senso per me ora e il comando reset funziona perfettamente per la mia situazione sopra. Ma quali sarebbero i comandi per accettare il riferimento al sottomodulo dal ramo master e buttare via il riferimento al sottomodulo del ramo corrente? So come gestire i conflitti normali, ma dopo tre giorni di analisi del Web, non riesco a trovare un esempio di codice diverso da rm -r. E sto cominciando a pensare che ci sia una ragione per cui gli esempi non esistono; i sottomoduli sono così lontani dal superprogetto che devi gestire ogni transizione.
Tyler,

26
FINALMENTE! Una domanda! Ho avuto added by us: ../Mono.Cecilin git statusma git adde git rmvenuto a mancare con Mono.Cecil: needs merge, pathspec 'Mono.Cecil/' did not match any filesperché era solo una cartella vuota e git veramente solo i file di maniglie.git checkoutmi ha dato Mono.Cecil: needs merge, error: you need to resolve your current index first, git submodule updatedato Skipping unmerged submodule Mono.Cecile git checkout master Mono.Cecilinfine risolto. Problema di base: il git statussuggerimento è sbagliato, quindi scegli un ramo e prendi la sua copia della cartella con checkout!
IBBoard,

6
Il comando di @ IBBoard mi ha aiutato in questa situazione - ho provato git checkout --ours SUBMODe git add SUBMODe altri, ma alla fine git checkout master SUBMODrisolto il conflitto. Questo commento dovrebbe probabilmente essere una risposta, non un commento ... :)
Colin D Bennett,

89

Bene, non è tecnicamente gestire i conflitti con i sottomoduli (cioè: mantieni questo ma non quello), ma ho trovato un modo per continuare a lavorare ... e tutto quello che dovevo fare era prestare attenzione al mio git statusoutput e ripristinare i sottomoduli:

git reset HEAD subby
git commit

Ciò ripristinerebbe il sottomodulo al commit pre-pull. Che in questo caso è esattamente quello che volevo. E in altri casi in cui ho bisogno delle modifiche applicate al sottomodulo, gestirò quelle con i flussi di lavoro del sottomodulo standard (checkout master, abbassa il tag desiderato, ecc.).


Per me questo sembra solo cambiare lo stato del modulo in conflitto da "entrambi modificati" a "eliminati".
Matt Zukowski,

4
In alternativa, potresti voler mantenere il sottomodulo della succursale unita: git reset <brash-branch> subby
Edward Anderson,

1
funziona per me come prescritto nella risposta. git reset HEAD path / to / submodule / dir
estoy

56

Ho faticato un po 'con le risposte a questa domanda e non ho avuto molta fortuna con le risposte in un post SO simile . Quindi questo è ciò che ha funzionato per me, tenendo presente che nel mio caso, il sottomodulo è stato gestito da un team diverso, quindi il conflitto è venuto da diverse versioni di sottomodulo in master e il mio ramo locale del progetto a cui stavo lavorando:

  1. Esegui git status: annota la cartella del sottomodulo con conflitti
  2. Reimpostare il sottomodulo sulla versione che è stata salvata l'ultima volta nel ramo corrente:

    git reset HEAD path/to/submodule

  3. A questo punto, hai una versione senza conflitti del tuo sottomodulo che ora puoi aggiornare all'ultima versione nel repository del sottomodulo:

    percorso cd / to / submodule
    git sottomodulo foreach git pull origin SUBMODULE-BRANCH-NAME
  4. E ora puoi commitfarlo e tornare al lavoro.


16

Per prima cosa, trova l'hash che vuoi fare riferimento al tuo sottomodulo. quindi corri

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

che ha funzionato per me per ottenere il mio sottomodulo con il riferimento hash corretto e continuare con il mio lavoro senza ulteriori conflitti.


1
o potresti semplicemente fare un checkout git - theirs (o --ours) subby
Bachi

@Bachi: git checkout - theirs e --ours non ha alcun effetto sui sottomoduli.
Edward Anderson,

1
Sebbene ciò risolva il conflitto, non è facile determinare <hashpointerhere>. Non conosco un modo semplice per vedere il commit del sottomodulo verificato su ogni lato del conflitto. Qualunque commit eseguito in subby può essere diverso da entrambi i lati dell'unione, il che non è appropriato in un commit di unione.
Edward Anderson,

@nilbus questo è vero. Abbiamo abbandonato il lavoro con i sottomoduli git in quanto questa era una delle preoccupazioni che avevamo e reso molto difficile capire quale impegno desideravi davvero. Abbiamo usato compositore (php) come gestore di pacchetti, che in realtà mi piace poiché crea un file di blocco che blocca i repository di un determinato hash. Tuttavia, poiché stiamo usando node_modules all'interno di più repository, incontreremmo moduli in conflitto qua e là. Da allora siamo passati a npm per gestire queste cose, ma questa è anche un'altra lattina di worm.
hellatan,

12

Ho avuto questo problema con git rebase -i origin/masterun ramo. Volevo prendere la versione principale del riferimento al sottomodulo, quindi ho semplicemente fatto:

git reset master path/to/submodule

e poi

git rebase --continue

Ciò ha risolto il problema per me.


3
Questo ha funzionato per me. Sto ancora immaginando cosa hanno fatto per danneggiare il sottomodulo
Checo R

3

Ho ricevuto aiuto da questa discussione. Nel mio caso il

git reset HEAD subby
git commit

ha funzionato per me :)


2

Bene, nella mia directory principale vedo:

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

Quindi l'ho appena fatto

git reset HEAD linux
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.