2014-10-28 13 views
10

Ho due rami A e B. Entrambi contengono un sottomodulo (nella cartella sub), tuttavia con commit diversi (che non avviano rapidamente da uno all'altro).Come risolvere il conflitto del modulo sottotitolo git se il sottomodulo non è inizializzato

A B 
|/
BASE 

ho verificato A, ma il modulo non è ancora inizializzato. Ora mi unisco allo B e ho un conflitto sul sottomodulo.

$ git status 
Unmerged paths: 
    (use "git add <file>..." to mark resolution) 

     both modified: sub 

emissione git checkout --ours sub non fa nulla (se il modulo viene inizializzato funziona, anche git checkout-index -f --stage=2 -- sub non funziona). git add sub causa l'errore error: pathspec 'sub' did not match any file(s) known to git..

$ git diff sub 
diff --cc sub 
index 533da4e,ab2af77..0000000 
--- a/sub 
+++ b/sub 
@@@ -1,1 -1,1 +1,1 @@@ 
- Subproject commit 533da4ea00703f4ad6d5518e1ce81d20261c40c0 
-Subproject commit ab2af775ec467ebb328a7374653f247920f258f3 
++Subproject commit 0000000000000000000000000000000000000000 

git submodule init -- sub non fa nulla. Anche git submodule update --init --force -- sub non funziona: Skipping unmerged submodule sub.

Quindi, come posso risolvere questo conflitto di sottomodulo (senza interrompere l'unione e riprovare dopo l'inizializzazione del sottomodulo)?

risposta

12

Ciò che rende la vostra situazione seccante è che git non ti permettono di inizializzare un modulo unmerged, quindi il consiglio ordinario sufficiente impostare il modulo per lo stato che si desidera all'interno del modulo poi eseguire git add non funzionerà. Quello che puoi fare è aggiornare l'indice direttamente, senza passare attraverso l'albero di lavoro.

Un modo per aggiornare l'indice è con git reset. Se conosci un commit in cui il sottomodulo si trova nello stato desiderato, puoi utilizzarlo. Ad esempio, uno dei seguenti potrebbe essere ciò che si vuole:

git reset master -- sub 
git reset [email protected]{upstream} -- sub 
git reset HEAD -- sub 
git reset MERGE_HEAD -- sub 

L'altra opzione è quella di aggiornare l'indice direttamente con il comando idraulico git update-index. Per fare ciò, è necessario sapere che un oggetto di tipo gitlink (cioè, la voce di directory in un repository principale che punta a un sottomodulo) è 0160000. Non c'è modo di capirlo dai primi principi, ma si può capire da git ls-files -s o il seguente riferimento (vedi "1110 (gitlink)" sotto 4 bit tipo di oggetto): https://github.com/gitster/git/blob/master/Documentation/technical/index-format.txt

per utilizzare questo approccio, a capire l'hash che si desidera impostare il modulo a, quindi eseguire, ad esempio:

git update-index --cacheinfo 0160000,533da4ea00703f4ad6d5518e1ce81d20261c40c0,sub 
2

Questo funziona come un'unione ordinaria: devi fornire il contenuto corretto su quel percorso in modo che git possa eseguirlo. Il contenuto del submodule è memorizzato come id di commit corrente, quindi devi aggiungere il percorso del sottomodulo al progetto (proprio come aggiungi il percorso di qualsiasi file) quando ha il contenuto giusto, che qui significa che il suo HEAD fa riferimento al commit corretto. Di solito lo ottieni con un normale checkout.

Nel tuo caso, non è possibile avere il contenuto del risultato di unione corretto nel percorso del modulo secondario e nessun contenuto. L'unica cosa necessaria è di avere un repository su quel percorso con l'ID di commit corretto in HEAD. Il repository contenente davvero non potrebbe importare di meno da dove proviene il repository del sottomodulo in quel percorso, l'unica cosa che conta a questo punto è l'ID commit in HEAD.

+2

Bene "Funziona come un'unione ordinaria", tuttavia 'git checkout --ours' e' git add' non funzionano. Come "fornire il contenuto corretto in quel percorso"?- "L'unica cosa necessaria è avere un repository su quel percorso con l'id di commit corretto in HEAD", ma come posso ottenerlo poiché l'inizializzazione del sottomodulo non funziona? – MrTux

+0

Un sottomodulo è solo un repo. "L'unica cosa necessaria è avere un ** repo ** su quel percorso". 'git clone u: // r/l -b $ yourbranch path/to/repo; git add path/to/repo; git commit -m done'. – jthill

+0

Questa opzione ha funzionato per me. Ho semplicemente clonato la versione corretta del repository mancante nella posizione del sottomodulo e quindi l'unione è andata avanti. –

Problemi correlati