Ho incontrato un conflitto di unione. Come posso interrompere l'unione?


2539

Ho usato git pulle ho avuto un conflitto di unione:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

So che l'altra versione del file è buona e che la mia è cattiva, quindi tutte le mie modifiche dovrebbero essere abbandonate. Come posso fare questo?


30
Mi rendo conto che questa è una domanda molto vecchia, ma vuoi interrompere l' intera unione e lasciare il ramo che stavi unendo senza fusione o semplicemente ignorare questo file come parte di una fusione più grande, lasciando che tutti gli altri file si uniscano come normale? Per me, il tuo titolo implica il primo, il tuo corpo di domanda vuole il secondo. Le risposte fanno entrambe le cose, senza chiarire le cose.
rjmunro,

Ho ottenuto un caso simile su commit dicendo che l'unione automatica non è riuscita; risolvere i conflitti e poi commettere il risultato:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana

4
Gwyn, potrebbe essere utile selezionare una risposta accettata qui. Il più votato è un po 'meno sicuro di alcune delle soluzioni più aggiornate, quindi penso che aiuterebbe a mettere in evidenza gli altri su di esso :)
Amicable

Risposte:


2222

Dato che non hai pullavuto successo, allora HEAD(no HEAD^) è l'ultimo commit "valido" sul tuo ramo:

git reset --hard HEAD

L'altro pezzo che vuoi è lasciare che i loro cambiamenti prevalgano sui tuoi cambiamenti.

Le versioni precedenti di git ti consentivano di utilizzare la strategia di unione "loro":

git pull --strategy=theirs remote_branch

Ma questo è stato rimosso, come spiegato in questo messaggio da Junio ​​Hamano (il manutentore di Git). Come notato nel link , invece faresti questo:

git fetch origin
git reset --hard origin

49
Invece di fare un hard reset, potresti portarlo a un livello più granulare facendo: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Non uso più git pull. Dal momento che in una lotta tra il mio ultimo codice e l'origine, l'origine dovrebbe sempre vincere, io sempre git fetche git rebase origin. Questo in realtà rende le mie fusioni e conflitti pochi e lontani tra loro.
Kzqai,

7
Sono d'accordo. Mi piace anche recuperare prima, quindi esaminare le modifiche a monte ( git log ..@{upstream}o git diff ..@{upstream}). Dopodiché, come te, rifarò il mio lavoro.
Pat Notz,

162
Come notato in una risposta più recente, a partire dalla versione 1.6.1, è possibile utilizzare 'git reset --merge'
Matt Ball

5
Ho usato git merge -X theirs remote_branchinvece git pull --strategy=theirs remote_branchcome theirssembra un'opzione direcursive
mlt

14
git merge --abortè di gran lunga preferibile.
Daniel Cassidy,

1956

Se la tua versione di git è> = 1.6.1, puoi usare git reset --merge.

Inoltre, come menziona @Michael Johnson, se la tua versione git è> = 1.7.4, puoi anche usare git merge --abort.

Come sempre, assicurati di non aver apportato modifiche senza commit prima di iniziare l'unione.

Dalla pagina man di git merge

git merge --abortè equivalente a git reset --mergequando MERGE_HEADè presente.

MERGE_HEAD è presente quando è in corso un'unione.

Inoltre, per quanto riguarda le modifiche non impegnate all'avvio di un'unione:

Se sono presenti modifiche che non si desidera eseguire il commit prima di iniziare un'unione, solo git stashprima della fusione e git stash popdopo aver terminato l'unione o interrotto.


3
Interessante - ma il manuale mi spaventa. Quando è esattamente appropriato usare? Quando dovresti specificare il facoltativo <commit>? #GitMoment: -o
conny

1
In genere lo si utilizza quando si desidera ripetere l'unione dall'inizio. Non ho mai dovuto specificare il commit opzionale da solo, quindi il default (nessun <commit> opzionale) va bene.
Carl,

44
Vorrei che questa risposta avesse più voti! A questo punto, sembra la soluzione più pertinente in molti casi.
Jay Taylor,

1
Anche con modifiche non impegnate, git è stato in grado di ripristinare lo stato prima dell'unione. Bello!
T3rm1,

2
È git merge --abortsolo un sinonimo di git reset --merge? Il nome ha sicuramente più senso, ma ha la stessa funzionalità?
Tikhon Jelvis,

518
git merge --abort

Annullare l'attuale processo di risoluzione dei conflitti e provare a ricostruire lo stato di pre-unione.

Se all'avvio dell'unione fossero presenti modifiche di worktree senza commit, git merge --abortin alcuni casi non sarà possibile ricostruirle. Si consiglia pertanto di eseguire sempre il commit o il salvataggio delle modifiche prima di eseguire git merge.

git merge --abortè equivalente a git reset --mergequando MERGE_HEADè presente.

http://www.git-scm.com/docs/git-merge


16
Questo è disponibile da git v1.7.4. È un alias per git reset --merge.
Michael Johnson,

162

È così semplice

git merge --abort

Git stesso ti mostra la soluzione quando ti trovi in ​​questo tipo di problema ed esegui il comando git status.

git status

Spero che questo possa aiutare le persone.


97

Penso che sia git resetnecessario.

Attenzione, ciò git revertsignifica qualcosa di molto diverso, per esempio, svn revert- in Subversion il ripristino eliminerà le modifiche (non confermate), restituendo il file alla versione corrente dal repository, mentre git revert"annulla" un commit.

git resetdovrebbe fare l'equivalente di svn revert, ovvero, scartare le modifiche indesiderate.


76

In questo particolare caso d'uso, non si desidera interrompere definitivamente l'unione, ma risolvere il conflitto in un modo particolare.

Non è nemmeno necessario ripristinare ed eseguire un'unione con una strategia diversa. I conflitti sono stati correttamente evidenziati da git e il requisito di accettare le modifiche degli altri lati è solo per questo file.

Per un file non unito in un conflitto, git rende disponibili l'indice nella versione base, locale e remota del file. (Qui è dove vengono letti per l'uso in uno strumento diff a 3 vie git mergetool.) Puoi usarli git showper visualizzarli.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

Il modo più semplice per risolvere il conflitto per usare la versione remota alla lettera è:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

Oppure, con git> = 1.6.1:

git checkout --theirs _widget.html.erb

5
grazie per il suggerimento. questo non sa di un'interfaccia utente scadente?
Peter,

@Peter: non sono convinto. Il risultato desiderato è ottenibile con pochi comandi di base con opzioni semplici. Quali miglioramenti suggeriresti?
CB Bailey,

10
Penso che il git 1.6.1comando abbia molto senso ed è buono. Questo è esattamente quello che avrei voluto. Penso che la soluzione pre-1.6.1 non sia elegante e richieda la conoscenza di altre parti di Git che dovrebbero essere separate dal processo di risoluzione della fusione. Ma la nuova versione è fantastica!
Peter,

67

Per uno scenario simile, l'ho fatto git fetche git pullpoi ho capito che il ramo a monte non era il ramo principale, il che ha provocato conflitti indesiderati.

git reset --merge 

Questo è tornato indietro senza ripristinare le mie modifiche locali.


45

I commenti suggeriscono che git reset --mergeè un alias per git merge --abort. Vale la pena notare che git merge --abortè equivalente a git reset --mergedato che a MERGE_HEADè presente. Questo può essere letto nella guida di git per il comando merge.

git merge --abort è equivalente a git reset --merge quando è presente MERGE_HEAD.

Dopo una fusione fallita, quando non c'è MERGE_HEAD, la fusione fallita può essere annullata git reset --merge, ma non necessariamente con git merge --abort. Non sono solo vecchia e nuova sintassi per la stessa cosa .

Personalmente, trovo git reset --mergemolto più potente per scenari simili a quello descritto e le fusioni fallite in generale.


2
cosa si intende qui in realtà con "unione fallita"? Unire conflitti o qualcos'altro? O per riformularlo: quando MERGE_HEAD non è presente? La mia domanda di follow-up è lì per capire un uso migliore di "git reset --merge".
Ewoks,

@Ewoks ha git stash applycausato un conflitto di unione per me, ma git merge --abortnon ha aiutato mentre lo git reset --mergefaceva.
nitzel,

27

Se si finisce con un conflitto di unione e non si ha nulla da impegnare, viene comunque visualizzato un errore di unione. Dopo aver applicato tutti i comandi di seguito indicati,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

Si prega di rimuovere

.git \ index.lock

File [taglia incolla in un'altra posizione in caso di ripristino], quindi inserisci uno dei comandi seguenti a seconda della versione desiderata.

git reset --hard HEAD
git reset --hard origin

Spero che aiuti!!!


19

Un'alternativa, che conserva lo stato della copia di lavoro è:

git stash
git merge --abort
git stash pop

In genere sconsiglio, perché è effettivamente come fondersi in Subversion poiché elimina le relazioni di filiale nel seguente commit.


Ho trovato questo approccio utile quando mi sono accidentalmente unito a un ramo git-svn, che non lo gestisce bene. Le fusioni di squash o le selezioni di ciliegie sono migliori quando si lavora con rami di tracciamento git-svn. In effetti la mia soluzione trasforma una fusione in una fusione di zucca dopo il fatto.
Alain O'Dea,

Migliore risposta alla domanda
Fouad Boukredine,

18

Poiché Git 1.6.1.3 git checkoutè stato in grado di effettuare il checkout da entrambi i lati di un'unione:

git checkout --theirs _widget.html.erb

3

Ho trovato il seguente ha funzionato per me (ripristinare un singolo file per pre-unire lo stato):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

-5

Sorgenti

Poiché non esegui il commit della tua unione, fai semplicemente doppio clic su un altro ramo (il che significa verificarlo) e quando sourcetree ti chiede di annullare tutte le modifiche, accetta :)

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.