Annulla un'unione Git che non è stata ancora spinta


3945

All'interno del mio ramo principale, ho fatto un git merge some-other-branchlocale, ma non ho mai spinto le modifiche al master di origine. Non intendevo unirmi, quindi mi piacerebbe annullarlo. Quando facevo un git statusafter my merge, stavo ricevendo questo messaggio:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

Sulla base di alcune istruzioni che ho trovato , ho provato a correre

git revert HEAD -m 1

ma ora ricevo questo messaggio con git status:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

Non voglio che la mia filiale sia in vantaggio per un numero qualsiasi di commit. Come posso tornare a quel punto?


3
Se hai bisogno di preservare la storia, in altre parole c'è un cambiamento che qualcuno ti ha mai tolto o che l'hai spinto da qualche parte usa la soluzione in Yuri Ushakov rispondi in basso!
Sedrik,

6
Deseleziona l'attuale risposta vincente, non è sicura (come molti hanno sottolineato) anche se continua a raccogliere voti. Per me "MBO" sembra il migliore, anche se ha molti meno punti.
inger il



3
Questa è una grande risorsa direttamente da Github: Come annullare (quasi) qualsiasi cosa con Git
jasonleonhard

Risposte:


4461

Con git reflogverifica quale commit è uno prima della fusione ( git reflogsarà un'opzione migliore di git log). Quindi è possibile ripristinarlo utilizzando:

git reset --hard commit_sha

C'è anche un altro modo:

git reset --hard HEAD~1

Ti restituirà 1 commit.

Tenere presente che tutti i file modificati e non compressi / non compressi verranno ripristinati al loro stato non modificato . Per tenerli nascosti o modificare le modifiche o vedere l' --mergeopzione di seguito.


Come suggerito da @Velmont di seguito nella sua risposta, in questo caso diretto usando:

git reset --hard ORIG_HEAD

potrebbe produrre risultati migliori, poiché dovrebbe preservare le modifiche. ORIG_HEADindicherà un commit direttamente prima che si verifichi l'unione, quindi non devi cercarlo da solo.


Un ulteriore suggerimento è utilizzare l' --mergeopzione invece di --hardnon ripristinare inutilmente i file:

git reset --merge ORIG_HEAD

--merge

Reimposta l'indice e aggiorna i file dell'albero di lavoro che sono diversi tra <commit> e HEAD, ma mantiene quelli che sono diversi tra l'indice e l'albero di lavoro (ovvero che hanno modifiche che non sono state aggiunte).


129
Non credo che questo funzionerà (sempre?) - "uno prima dell'unione" sarà il commit più recente che è stato unito dall'altro ramo - non sarà il commit più recente sul ramo corrente . Giusto? (Questo potrebbe essere solo il risultato di ciò che git logsceglie di mostrare per impostazione predefinita - forse c'è un output diverso git logo git reflogpotrebbe essere utilizzato per questo)
John Bachir

6
Penso che potrebbe dipendere dal fatto che si unisca la zucca.
Marcin Gil,

29
@JohnBachir ha ragione. In git loguscita, si vuole guardare ai due commit genitore. Uno è l'ultimo commit nel tuo ramo, uno è l'ultimo commit nel ramo in cui ti sei unito. Desideri eseguire git reset --hardil commit del genitore sul ramo in cui ti sei unito.
Giustino,

7
@JohnBachir: Fintanto che la "fusione" non è in realtà un avanzamento veloce, si tradurrà in un nuovo commit che si trova nella parte superiore del registro e questo commit ha due genitori (o più di 2 se si fa un polpo merge). Se rimuovi questo commit di unione, anche tutti i commit più vecchi che sono arrivati ​​dall'unione scompariranno. Per sicurezza, però, dopo un reset git ti dirà dove si trova la nuova testa: "HEAD è ora a 88a04de <messaggio di commit>". Lo guardo sempre per assicurarmi di essere finito dove mi aspettavo di essere. Il mio progetto utilizza uno schema di denominazione delle filiali standard per mantenere le cose memorabili.
Mark E. Haase,

44
Quello che ho trovato utile è stato guardare "git reflog" e cercare l'ultimo commit che ho fatto in master. Quindi faigit reset --hard <commit_sha>
Max Williams il

1456

Supponendo che il tuo master locale non fosse in anticipo rispetto a origin / master, dovresti essere in grado di farlo

git reset --hard origin/master

Quindi la tua masterfiliale locale dovrebbe apparire identica a origin/master.


71
@Carter in realtà non è la risposta migliore. È possibile che origine / master possano essere in anticipo rispetto al master locale appena prima della fusione di alcuni commit, in tal caso ciò potrebbe non dare i risultati desiderati
Dhruva Sagar,

15
@ dhruva-sagar Sì, ma fintanto che git non dice che sei dietro e non vai a prendere, dovresti stare bene.
Kelvin,

3
Grazie! Questo è perfetto se (e solo se) hai un repository remoto.
tomc

2
No, non è quello perfetto per questa domanda, vedi la clausola "assume". La risposta di MBO in realtà copre questo caso e il caso in cui l'unione non è l'unico commit locale.
inger il

2
Ancora una volta, forse questo avviso dovrebbe andare nella risposta stessa: evitare sempre di riscrivere la cronologia di git!
Cregox,

1175

Vedi il capitolo 4 del libro Git e il post originale di Linus Torvalds .

Per annullare una fusione già spinta :

git revert -m 1 commit_hash

Assicurati di ripristinare il ripristino se stai commettendo di nuovo il ramo, come ha detto Linus.


10
@perfezionista concordato :) Tipo di desiderio c'era un modo per migrare questa risposta ad un'altra
domanda--

per ulteriori informazioni sul ripristino: link
assaqqaf

1
Per essere sicuri che questo ripristino abbia funzionato, puoi fare git diff hash1 hash2 dove hash1 è il ripristino del commit e hash2 è il vecchio commit di cui stai tentando di tornare. Nessun risultato == successo! Sono stato in grado di ripristinare più commit eseguendo questa operazione più volte, iniziando ripristinando la fusione più recente e lavorando all'indietro. git diff mi ha mostrato che sono finito nello stato che volevo.
Robert Sinton,

6
Si noti che questo non non realmente risolvere la questione sollevata dal manifesto originale . Il poster originale già utilizzato git revert -m 1 <commit>. Il problema è che farlo non cancella l'unione accidentale che ha fatto (e non ha ancora spinto). Le altre risposte che coinvolgono ripristini forzati sono migliori per il problema del poster originale.

Questa è una grande risorsa direttamente da Github: Come annullare (quasi) qualsiasi cosa con Git
jasonleonhard

986

È strano che mancasse il comando più semplice. La maggior parte delle risposte funziona, ma annullando l'unione che hai appena fatto, questo è il modo semplice e sicuro :

git reset --merge ORIG_HEAD

L'arbitro ORIG_HEADpunterà al commit originale prima della fusione.

(L' --mergeopzione non ha nulla a che fare con l'unione. È proprio come git reset --hard ORIG_HEAD, ma più sicura poiché non tocca le modifiche non confermate.)


17
Se hai sporcato il tuo albero di lavoro da allora, git reset --merge ORIG_HEADconserva quelle modifiche.
gridò l'

1
Questa è l' unica risposta corretta (non sto dicendo che questa è la risposta migliore - notare la differenza). Diciamo, sul master, ho fatto 3 commit a t1, t3 e t5. Diciamo, su branch1, ho fatto 3 commenti su t2, t4 e t6 (supponiamo che t1, t2, t3, t4, t5 e t6 siano in ordine cronologico). Qualsiasi comando simile git reset --hard HEAD~5ripristinerà solo HEAD (può rimuovere i commit sia in master che in branch1). Solo l' --mergeopzione rimuove il merge.
Manu Manjunath,

@Manu L' --mergeopzione in realtà non rimuove l'unione, puoi usarla --hardfunzionerà anche bene. È il riferimento ORIG_HEAD che è l'indizio qui, è impostato prima di fare una fusione a dove ti trovi in ​​quel punto. :)
odinho - Velmont,

@yingted cosa intendi con "Se hai sporcato il tuo albero di lavoro da allora, git reset --merge ORIG_HEAD conserva queste modifiche." Intendevi cambiare i file dopo l'unione? Ad ogni modo ho fatto l'unione e poi ho risolto alcuni conflitti. Ma poi ho voluto ripristinare l'unione e ho fatto come indicato in questa risposta. Tutto è andato bene e non ha conservato le modifiche apportate dopo l'unione. Il mio repository locale è simile alla posizione precedente alla fusione.
Samitha Chathuranga,

Il git reset --hard ORIG_HEADcomando ha funzionato perfettamente per me - potrebbe essere stato aiutato dal fatto che non ho apportato altre modifiche al repository dopo il locale git mergeche stavo cercando di annullare. Il comando ripristina semplicemente lo stato del repository su come era prima dell'unione. Grazie per l'ottimo consiglio!
bluebinary,

391

Con le versioni Git più recenti, se non hai ancora eseguito il commit dell'unione e hai un conflitto di unione , puoi semplicemente fare:

git merge --abort

Da man git merge:

[Questo] può essere eseguito solo dopo che l'unione ha provocato conflitti. git merge --abortinterromperà il processo di unione e proverà a ricostruire lo stato di pre-unione.


8
La sua unione è impegnata ma non forzata (vedi titolo), si è già unito, il tuo comando funziona solo quando è ancora nel mezzo di un'unione
JBoy

135

È necessario ripristinare il commit precedente. Questo dovrebbe funzionare:

git reset --hard HEAD^

O anche HEAD^^per ripristinare quel commit di ripristino. Puoi sempre fornire un riferimento SHA completo se non sei sicuro di quanti passi indietro dovresti fare.

Nel caso in cui si riscontrino problemi e il ramo master non abbia subito modifiche locali, è possibile ripristinare origin/master.


5
La migliore risposta IMHO, incorpora quella dell'OP (assumendo solo 1 passaggio da ripristinare, che sembrava essere il caso nella Q), così come quello di randomguy3 (che funziona quando "il tuo ramo master non ha avuto cambiamenti locali ")
inger il

4
Commentatori, @Inger e @Konstantin, perché? Sei venuto qui dopo che la mia risposta è stata creata ed è più corretta. Salire la HEAD di un passo è spesso sbagliato e dovresti davvero contare fino a che punto devi andare. Git è già impostato ORIG_HEADper te, perché non utilizzarlo?
Odinho - Velmont,

ripristinerà anche le modifiche locali? #Per favore aggiornare.
CoDe

Questo ha funzionato perfettamente per me, ripristinare la testa in questo modo ha molto più senso della metà delle risposte qui.
Varda Elentári,

HEAD ^ uguale a commit prima di HEAD? e ^^ è già stato eseguito il commit di due commit? Indovinare che non funzionerà con le fusioni in avanti veloce?
Marcus Leon,

87

Ultimamente, ho usato git reflogper aiutare con questo. Questo funziona principalmente solo se l'unione è avvenuta SOLO, ed era sulla tua macchina.

git reflog potrebbe restituire qualcosa del tipo:

fbb0c0f HEAD@{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 HEAD@{1}: checkout: moving from master to my-branch
e3753a7 HEAD@{2}: rebase finished: returning to refs/heads/master
e3753a7 HEAD@{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 HEAD@{4}: reset: moving to HEAD^
8400a0f HEAD@{5}: rebase: aborting

La prima riga indica che si è verificata un'unione. La seconda riga è il tempo prima della mia unione. Devo semplicemente git reset --hard 43b6032forzare questo ramo a rintracciare prima della fusione e proseguire.


Ottima risposta, grazie! Avevo bisogno di annullare un'unione, ma le altre risposte l'hanno semplicemente incasinata di più, usando reflogper ottenere lo SHA e farlo git resetfunzionare.
Lankymart,

51

Con Git moderno puoi:

git merge --abort

Sintassi precedente:

git reset --merge

Vecchia scuola:

git reset --hard

Ma in realtà, vale la pena notare che git merge --abortè solo equivalente a git reset --mergedato che MERGE_HEADè presente. Questo può essere letto nella guida di Git per il comando di unione.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

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

Personalmente trovo git reset --mergemolto più potente e utile nel lavoro quotidiano, quindi è quello che uso sempre.


Ha funzionato alla grande per me. Ogni altro post dice che questo è così complicato, ma questo ha fatto esattamente quello che ci si aspetta. Suppongo che abbia funzionato solo perché c'erano conflitti, che non rispondono esattamente alla domanda originale.
Jeremy,

Questa risposta non si concentra sulla situazione del PO e lascia fuori un contesto importante.
Ben Wheeler,

37

Ok, le risposte che altre persone qui mi hanno dato sono state vicine, ma non ha funzionato. Ecco cosa ho fatto.

Facendo questo...

git reset --hard HEAD^
git status

... mi ha dato il seguente status.

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

Ho quindi dovuto digitare lo stesso git resetcomando più volte. Ogni volta che l'ho fatto, il messaggio è cambiato di uno come puoi vedere di seguito.

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

A questo punto, ho visto il messaggio di stato cambiato, quindi ho provato a fare un git pull, e sembrava funzionare:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

Per farla breve, i miei comandi sono arrivati ​​a questo:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull

19
o avresti potuto usareHEAD^^^^
hasen

17
forse anche resettato a origin/master;)
hasen

23

È possibile utilizzare git reflogper trovare il checkout precedente. A volte è un buon stato in cui vuoi tornare.

concretamente,

$ git reflog
$ git reset --hard HEAD@{0}

1
Grazie! Hai risparmiato mezza giornata del mio lavoro. Tuttavia non ho potuto uscire dalla modalità reflog con nessun comando.
Katarzyna,

1
@Katarzyna usa il tasto "q" per uscire dal reflog
Amjed Baig

21

Se sei nel mezzo della fusione, puoi sempre interromperlo git merge --abort


2
grazie fratello e stavo per fare quella risposta spaventosa. fortunatamente ho scorrere verso il basso. voglio solo cancellare la testa di unione
Nyuu

15

Sono stato in grado di risolvere questo problema con un singolo comando che non comporta la ricerca di un ID commit.

git reset --hard remotes/origin/HEAD

La risposta accettata non ha funzionato per me, ma questo comando ha ottenuto i risultati che stavo cercando.


Esattamente! Reimposta le tue modifiche all'HEAD del ramo! Non fare uno per uno
Carlos Zinato,

non ha funzionato per me. in realtà finì per rispedire la filiale locale un mese o due. Per fortuna questo è tutto locale, quindi posso sempre distruggere il ramo e recuperarlo di nuovo. Volevo solo sottolinearlo nel caso altri lo provassero.
Matt Pengelly,

@MattPengelly questo metodo è ampiamente non documentato e di solito funziona se il tuo ramo è sincronizzato con il ramo remoto prima che tu abbia fatto l'unione. Sono passati mesi da quando il tuo ramo era sincronizzato con il ramo remoto?
Ralph Ritoch,

@MattPengelly dipende anche da quale ramo è indicato HEAD. Sto usando gitflow su uno dei miei progetti e anche se sono nel ramo di sviluppo, i telecomandi / origine / HEAD sono puntati su origine / master, quindi se avessi bisogno di annullare un'unione probabilmente avrei bisogno di resettare per telecomandi / origine / sviluppo
Ralph Ritoch,

14

Se non l'hai ancora fatto, puoi solo usare

$ git checkout -f

Annullerà l'unione (e tutto ciò che hai fatto).


Ho provato questo e in realtà ha aumentato il numero di commit che la mia filiale locale è in vantaggio.
barclay

14

Sono arrivato a questa domanda anche cercando di ripristinare la corrispondenza dell'origine (ovvero, NO si impegna prima dell'origine). Effettuando ulteriori ricerche, è emerso che esiste resetesattamente un comando per questo:

git reset --hard @{u}

Nota: @{u}è una scorciatoia per origin/master. (E, naturalmente, hai bisogno di quel repository remoto per farlo funzionare.)


14

Devi cambiare la TESTA, non la tua ovviamente, ma vai a TESTA ....

Quindi, prima di rispondere, aggiungiamo alcuni retroscena, spiegando di cosa si tratta HEAD.

First of all what is HEAD?

HEADè semplicemente un riferimento al commit corrente (più recente) sul ramo corrente.
Può essercene solo uno HEADin qualsiasi momento. (escluso git worktree)

Il contenuto di HEADè memorizzato all'interno .git/HEADe contiene i 40 byte SHA-1 del commit corrente.


detached HEAD

Se non si esegue l'ultimo commit, il che significa che HEADindica un commit precedente nella cronologia che viene chiamato detached HEAD.

inserisci qui la descrizione dell'immagine

Sulla riga di comando, sarà simile al seguente: SHA-1 invece del nome del ramo poiché HEADnon punta alla punta del ramo corrente

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Alcune opzioni su come recuperare da una HEAD staccata:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Questo verificherà il nuovo ramo che punta al commit desiderato.
Questo comando eseguirà il checkout per un determinato commit.
A questo punto, puoi creare un ramo e iniziare a lavorare da questo punto in poi.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Puoi sempre usare refloganche quello.
git reflogvisualizzerà qualsiasi modifica che ha aggiornato il HEADe il checkout della voce di reflog desiderata HEADriporterà questo commit.

Ogni volta che HEAD viene modificato, ci sarà una nuova voce in reflog

git reflog
git checkout HEAD@{...}

Questo ti riporterà al commit desiderato

inserisci qui la descrizione dell'immagine


git reset --hard <commit_id>

"Sposta" HEAD indietro al commit desiderato.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Nota: ( da Git 2.7 )
    puoi anche usare git rebase --no-autostashanche questo.

git revert <sha-1>

"Annulla" l'intervallo di commit o commit specificato.
Il comando reset "annulla" tutte le modifiche apportate nel commit dato.
Verrà eseguito il commit di un nuovo commit con la patch di annullamento mentre il commit originale rimarrà anche nella cronologia.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Questo schema illustra quale comando fa cosa.
Come puoi vedere, reset && checkoutmodifica il HEAD.

inserisci qui la descrizione dell'immagine


Questo è un tesoro 🐱‍👤🐱‍👤🐱‍👤
Jawand Singh,

12

La risposta più semplice è quella data da Odinho - Velmont

Prima di tutto git reset --merge ORIG_HEAD

Per coloro che desiderano reimpostare dopo che le modifiche sono state inviate, esegui questa operazione (poiché questo è il primo post visualizzato per qualsiasi domanda di merge git reset)

git push origin HEAD --force

Ciò verrà reimpostato in modo tale da non riavere indietro le modifiche unite dopo il pull.


10

Solo per un'opzione in più da guardare, ho principalmente seguito il modello di ramificazione descritto qui: http://nvie.com/posts/a-successful-git-branching-model/ e come tale mi sono unito--no-ff (no avanzamento veloce) di solito.

Ho appena letto questa pagina poiché ho accidentalmente unito un ramo di prova anziché il mio ramo di rilascio con master per la distribuzione (sito Web, master è ciò che è attivo). La filiale di test ha due altre filiali unite ad essa e ammonta a circa sei commit.

Quindi per ripristinare l'intero commit ne avevo solo bisogno git reset --hard HEAD^e ha ripristinato l'intera unione. Poiché le fusioni non sono state inoltrate rapidamente, la fusione è stata un blocco e un passo indietro è "ramo non unito".


10

È possibile utilizzare solo due comandi per ripristinare un'unione o riavviare con un commit specifico:

  1. git reset --hard commitHash (è necessario utilizzare il commit che si desidera riavviare, ad es. 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force (Invio del nuovo ramo principale locale a origine / principale)

Buona fortuna e vai avanti!


10

Può essere fatto in diversi modi.

1) Annulla unione

Se sei nel mezzo di una cattiva unione (erroneamente eseguita con un ramo sbagliato) e volevi evitare l'unione per tornare al ramo più recente come di seguito:

git merge --abort

2) Ripristinare HEAD sul ramo remoto

Se stai lavorando dal ramo di sviluppo remoto, puoi ripristinare HEAD all'ultimo commit sul ramo remoto come di seguito:

git reset --hard origin/develop

3) Elimina il ramo corrente ed esegui nuovamente il checkout dal repository remoto

Considerando che stai lavorando allo sviluppo del ramo nel repository locale, che si sincronizza con il ramo remoto / sviluppo, puoi fare come di seguito:

git checkout master 
##to delete one branch, you need to be on another branch, otherwise you will fall with the branch :) 

git branch -D develop
git checkout -b develop origin/develop

che "1) Abort Merge" era abbastanza carino. Upvoting.
CodeToLife

1
Stai attento! git merge --abort "può essere eseguito solo dopo che l'unione ha provocato conflitti. git merge --abort interromperà il processo di unione e proverà a ricostruire lo stato di pre-unione"
Pedro García Medina

8

Se la tua unione e i relativi commit non sono ancora stati inviati, puoi sempre passare a un altro ramo, eliminare quello originale e ricrearlo.

Ad esempio, ho accidentalmente unito un ramo di sviluppo in master e volevo annullarlo. Utilizzando i seguenti passaggi:

git checkout develop
git branch -D master
git branch -t master origin/master

Ecco! Il master è allo stesso livello dell'origine e il tuo stato di fusione errata viene cancellato.


1
Nota: ciò non solo annulla l'unione, ma anche tutti gli commit locali effettuati dall'ultimo push all'origine.
Martijn Heemels,

4

Se vuoi una soluzione da riga di comando, ti suggerisco di seguire la risposta di MBO.

Se sei un principiante, potrebbe piacere l'approccio grafico:

  1. Inizia gitk(dalla riga di comando o fai clic con il pulsante destro del mouse nel browser dei file se lo hai)
  2. Puoi facilmente individuare il commit di unione lì - il primo nodo dall'alto con due genitori
  3. Segui il link al primo / sinistra genitore (quello sul tuo ramo corrente prima dell'unione, di solito rosso per me)
  4. Sul commit selezionato, fai clic con il pulsante destro del mouse su "Ripristina ramo qui", seleziona lì il ripristino hardware

4

Strategia: creare un nuovo ramo da cui tutto andava bene.

Motivazione: Ripristinare un'unione è difficile. Esistono troppe soluzioni, a seconda di molti fattori, ad esempio se hai eseguito il commit o il push della tua unione o se ci sono stati nuovi commit dalla tua unione. Inoltre, devi ancora avere una conoscenza relativamente profonda di git per adattare queste soluzioni al tuo caso. Se segui ciecamente alcune istruzioni, puoi finire con una "fusione vuota" in cui nulla verrà unito e ulteriori tentativi di fusione faranno in modo che Git ti dica "Già aggiornato".

Soluzione:

Diciamo che si desidera unire devin feature-1.

  1. Trova la revisione che desideri ricevere l'unione:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. Dai un'occhiata (torna indietro nel tempo):

    git checkout e5f6g7h8
    
  3. Crea un nuovo ramo da lì e provalo:

    git checkout -b feature-1
    

Ora puoi riavviare l'unione:

  1. Merge: git merge dev

  2. Risolvi i conflitti di unione.

  3. Commettere: git commit

  4. Quando sei soddisfatto dei risultati, elimina il vecchio ramo: git branch --delete feature-1


2

Basta creare un nuovo ramo, quindi selezionare la ciliegina desiderata.

Il suo risparmio e più semplice ripristina quindi descritto in molte risposte sopra


1
Sono d'accordo con questo suggerimento, soprattutto se non ti senti completamente a tuo agio con i comandi git elencati. Questo può essere più lento con più "fatica", ma se non viene molto e ti preoccupi di perdere il lavoro, vale la pena.
Greg,

1

Penso che tu possa fare git rebase -i [hash] [branch_name] dov'è [hash]l'hash identificativo per quanto lontano indietro vuoi riavvolgere più uno (o comunque molti commit indietro che vuoi andare) e quindi eliminare le righe per i commit nell'editor che non vuoi più . Salva il file. Uscita. Pregare. E dovrebbe essere riavvolto. Potrebbe essere necessario fare un git reset --hard, ma dovrebbe essere buono a questo punto. Puoi anche usarlo per estrarre specifici commit da uno stack, se non vuoi tenerli nella tua cronologia, ma ciò può lasciare il tuo repository in uno stato che probabilmente non vuoi.


1

Se hai eseguito l'unione:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard

1
  1. Innanzitutto, assicurati di aver commesso tutto.

  2. Quindi ripristinare il repository allo stato di lavoro precedente:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    o usando --hard( questo rimuoverà tutte le modifiche locali e non impegnate! ):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    Usa l'hash presente prima del commit erroneamente unito.

  3. Controlla quali commit desideri ripetere il commit nella parte superiore della versione corretta precedente:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. Applica i tuoi commit giusti nella parte superiore della versione corretta del tuo repository:

    • Usando cherry-pick (le modifiche introdotte da alcuni commit esistenti)

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • O selezionando con cura la gamma di commit per:

      • Prima controlla le modifiche giuste prima di unirle:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • Prima controlla le modifiche giuste prima di unirle:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        dove si trova l'intervallo dei commit corretti che hai commesso (esclusa l'unione erroneamente impegnata).


1
  1. git stash

  2. git branch -d the_local_branch

  3. git checkout -t <name of remote>

  4. git stash apply

Questo ha funzionato per me .. !!


0

Se si nota che è necessario ripristinare immediatamente dopo l'unione e non hai fatto altro dopo il tentativo di unione, si può solo emettere questo comando: git reset --hard HEAD@{1}.

In sostanza, la tua unione shaindicherà HEAD@{0}se nient'altro è stato commesso dopo l'unione e così HEAD@{1}sarà il punto precedente prima dell'unione.


0

La più semplice delle possibilità più semplici, molto più semplice di qualsiasi altra cosa qui detta:

Rimuovi il tuo ramo locale (locale, non remoto) e tiralo di nuovo. In questo modo annullerai le modifiche sul tuo ramo principale e chiunque sarà interessato dalla modifica che non vuoi spingere. Ricominciare da capo.


0

In questo caso, dovrai ripristinare il tuo ramo con git reset --hard <branch_name>. Se si desidera salvare le modifiche prima di ripristinarle, assicurarsi di creare un nuovo ramo e git checkout <branch_name>.

Puoi anche reimpostare lo stato su un commit specifico git reset --hard <commit_id>.

Se le modifiche sono state inviate, è possibile utilizzare git revert <branch_name>invece. Assicurati di controllare come usare git revert e git checkout anche in altri scenari.

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.