2013-07-14 15 views
15

Attualmente ho due filiali su cui sto lavorando. A causa di un aggiornamento del software ho dovuto modificare completamente la struttura della cartella. Pertanto sposta i file in entrambi i rami. Ora ho raggiunto un punto in cui voglio unire il mio ramo di lavoro al mio ramo principale.git - Lo stesso file aggiunto da entrambi i rami causa un conflitto di unione strano

Il problema è che esistono conflitti di unione che indicano che un file è stato aggiunto da un solo ramo (added by them o added by us). Il problema è che il file è stato aggiunto da entrambi i rami.

Ad esempio, ho una trama a textures/texture1.png. Il ramo principale lo ha spostato nella posizione corretta (era prima dello misc/textures/texture1.png). Il ramo di lavoro lo spostò nello stesso identico luogo e lo modificò in seguito. Il conflitto di unione per questo file dice:

added by us: textures/texture1.png 

Il punto è che questo non è il file che voglio! Voglio il file dall'altro ramo!
Quando faccio

git checkout --theirs textures/texture1.png 

ottengo

error: path 'textures/texture1.png' does not have their veresion 

, ma questo file lo fa esiste! L'ho aggiunto di recente! E quello è il file che voglio

Come posso risolvere questi conflitti?

(ulteriori informazioni, se necessario!)

+0

laterale: git non riesco a dire che si sia rinominato il file e poi tu (ma non loro) hai modificato il file, dato che git esegue il rilevamento dinamico dei nomi e non è all'altezza del compito qui. Non ho mai provato a separare il commit del "file rinominato" dal commit di "modifica del file rinominato", anziché averli insieme, ma credo che averli separati avrebbe dato a git più possibilità di "capire le cose" per così dire. Sarebbe particolarmente utile con la tecnica "helper branch" descritta da @mnagel. – torek

risposta

8
a--b--c--M--d--f--E--g--h--i <<< master 
    \ 
    \ 
     x--M'--y--z    <<< you 

fa la situazione sembra un po 'come sopra (dove M e M' sono i commit in movimento ed e è il commit che pubblica le texture)? tu provi a unire z/i e git non è veramente felice.

si potrebbe provare a fondersi con M M' su un ramo temporaneo

a--b--c---M--d--f--E--g--h--i <<< master 
    \  \ 
    \  X     <<< helper 
     \ /
     x--M'--y--z    <<< you 

e quindi unire aiutante ("X") con voi ("z") e master ("i").

a--b--c---M--d--f--E--g--h--i  <<< master 
    \  \     \ 
    \  X-----XX---------XXX <<< helper 
     \ / /
     x--M'--y--z    <<< you 

in questo modo i conflitti vengono risolti direttamente dopo che sono stati creati e non trasportati. spesso questo è più facile perché i conflitti tendono a crescere nel tempo.

+0

Il punto è che E è nel ramo "tu". Ma ci proverò. E con il tuo metodo unisco semplicemente XXX Into Master? Perché è lì che voglio la fusione finale. – BrainStone

+1

non è molto importante su quale ramo E sia. l'importante è fare l'unione in anticipo e avere una risoluzione dei conflitti più semplice in questo modo (nessuna garanzia che funzioni effettivamente). quando hai uno stato come illustrato nel terzo grafico, puoi eseguire l'avanzamento rapido del master in helper/XXX senza conflitti, dato che XXX è un successore di i. – mnagel

+0

Questo ha funzionato per me! Grazie per aver aiutato un noob. La cronologia della rete su GitHub sembra divertente, ma va bene;) – BrainStone

9

Si può sempre provare

git mergetool 

questo aprirà una GUI, in cui è possibile scegliere le modifiche desiderate semplicemente clic sui collegamenti appropriati. A volte è necessario apportare modifiche manuali. Ma nel tuo caso devi solo selezionare un'immagine di file.

+0

Questo non aiuta Dato che mi dice solo lo stesso (che un ramo cancellato un file. Ma lo ha fatto ** non **!) – BrainStone

2

Mentre risoluzione dei conflitti basta usare git checkout che indica il diritto (nome del ramo, tag, SHA1 del commit ...) Albero-ish da cui si desidera ottenere un file:

git checkout theirBranchYouAreMerging -- textures/texture1.png 

Se non voglio tutte le "loro" modifiche, potresti quindi cancellarle parzialmente.Per questo si avrebbe bisogno git reset -p per rimuovere selettivamente ogni cambiamento indesiderato dall'indice, e poi git checkout per rimuoverli dalla directory di lavoro così: nota

git checkout theirBranch -- some/file.txt 
git reset -p -- some/file.txt 
git checkout -- some/file.txt