Ripristina un'unione Git


225
develop branch
--> dashboard (working branch)

Uso git merge --no-ff developper unire tutte le modifiche a monte nel dashboard

registro git:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <root@magneto.giveforward.com>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

La fusione aveva circa 50+ commit e mi sto chiedendo come ripristinare l'unione in modo che la dashboard torni allo stato di pre-fusione

La seconda parte di questo è che, se non mi unisco --no-ff, non riesco a far sì che il commit " Unisci ramo" si sviluppi "nel dashboard ". Come posso ripristinare tale unione?


3
Possibile duplicato della fusione Undo a Git? .

Risposte:


320

Il ripristino di un commit di unione è stato trattato in modo esauriente in altre domande. Quando esegui un'unione con avanzamento rapido, la seconda che descrivi, puoi utilizzare git resetper tornare allo stato precedente:

git reset --hard <commit_before_merge>

Puoi trovare <commit_before_merge>con git reflog, git logo, se senti il ​​moxy (e non hai fatto altro):git reset --hard HEAD@{1}


6
grazie per la rapida risposta .. guardando git log, il commit prima della fusione è di oltre 50 commit, poiché lo sviluppo di git merge mette effettivamente tutti gli altri commit. Immagino che cosa non ottengo è, se non so cosa / dove fosse quell'unione - come trovarlo? Hai detto di aver trovato il commit_before_merge .. Immagino di non capire quella parte
cgmckeever

4
sembra con git reflog sembra che riassuma bene le ultime teste e mi permette di sapere dove devo resettare. git log sembra avere troppa granularità per individuare il luogo in cui ripristinare. Grazie
cgmckeever il

1
Sì, è reflogun vero toccasana. HEAD@{1}descrive semplicemente il secondo stato più recente di HEAD, o più tecnicamente: "Un riferimento seguito dal suffisso @ con una specifica ordinale racchiusa in una coppia di parentesi graffe (ad esempio {1}, {15}) specifica l'n-esimo valore precedente di quello ref ".
Christopher,

4
Che ne dici di spingere il ripristino al telecomando? Non vedo come funzionerà.
Anton Savelyev,

2
Questo è senza speranza. Distrugge tutti i commit dopo l'unione.
aaa90210

151

Da qui:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git Revert aggiunge un nuovo commit che ripristina il commit specificato.

L'uso di -m 1 indica che si tratta di un'unione e che vogliamo eseguire il rollback al commit parent sul ramo master. Dovresti usare -m 2 per specificare il ramo di sviluppo.


30
Si noti che non è possibile ricollegare il ramo dopo questo, come dice la documentazione: "Il ripristino di un commit di unione dichiara che non si vorranno mai le modifiche dell'albero apportate dall'unione. Di conseguenza, le fusioni successive porteranno solo modifiche all'albero introdotte con commit che non sono antenati della fusione precedentemente annullata. Questo può essere o meno ciò che desideri. "
Dalibor Karlovic

23
@ DaliborKarlovic Questa affermazione è un po 'dura. Puoi sicuramente ripristinare queste modifiche in seguito, il trucco è ripristinare il commit di ripristino. Maggiori informazioni qui nella sezione "Ripristino del ripristino"
Hilikus,

3
Purtroppo, il herelink nel commento @Hilikus non è più valido. Il sito afferma che il contenuto è stato spostato in un libro ( git-scm.com/book/en/v2 ) ma, in tal caso, non è banale individuarlo.
Jesse Chisholm,

@ DaliborKarlovic è questo il caso con la risposta sopra di @Christopher?
James B,

3
L'annullamento della fusione dei contenuti è stato spostato qui
SEK

28

Basta ripristinare il commit di unione con git reset --hard HEAD^.

Se usi --no-ff git crea sempre un'unione, anche se non hai commesso nulla nel mezzo. Senza --no-ff git farà semplicemente un avanzamento veloce, il che significa che i tuoi rami HEAD saranno impostati su HEAD del ramo unito. Per risolvere questo problema, trova l'ID commit a cui desideri ripristinare e git reset --hard $COMMITID.


1
Buona soluzione se non si conosce il commit prima della fusione.
iglesiasedd,

Ha funzionato per me perché non conosco il commit id. + 1
Anant Singh --- Alive to Die

se l'unione indesiderata era già impegnata in remoto, ho usato git push -f per aggiornare il ramo remoto dopo il ripristino.
zumek,

16
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

Ma potrebbero avere effetti collaterali inaspettati. Vedi l' --mainline parent-numberopzione in git-scm.com/docs/git-revert

Forse un modo brutale ma efficace sarebbe quello di estrarre il genitore di sinistra di quel commit, fare una copia di tutti i file, effettuare HEADnuovamente il checkout e sostituire tutto il contenuto con i vecchi file. Quindi git ti dirà cosa viene eseguito il rollback e creerai il tuo commit di ripristino :)!


1
+1 perché questa risposta non confonde con la cronologia come fa il reset (molto importante se hai già inviato al telecomando). Ma quali effetti collaterali inaspettati dovrei aspettarmi?
pedromanoel,

3
È questo l'effetto collaterale che hai menzionato? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
pedromanoel,

1
Dici che git resetè la soluzione, ma menziona anche che potrebbe avere effetti collaterali inaspettati. Tuttavia, quel link proviene git revert, non git reset:)
Mark

2
Nota: git reset non ha un flag -m. Nota anche che @JorgeOrpinel fa riferimento ai documenti git-revert, non a git-reset. Penso che intendesse dire di git revertnogit reset
Devin Gleason Lambert,

È stato specificato come evitare Mainline ma il commit di 1234xyz non è un errore di unione .
Achal,

0

Se hai unito il ramo, hai ripristinato l'unione usando una richiesta pull e hai unito quella richiesta pull per ripristinare.

Il modo più semplice che ho sentito è stato di:

  1. Elimina un nuovo ramo da sviluppa / master (dove ti sei unito)
  2. Ripristina il "ripristino" utilizzando git revert -m 1 xxxxxx(se il ripristino è stato unito utilizzando un ramo) o utilizzando git revert xxxxxxse fosse un ripristino semplice
  3. Il nuovo ramo dovrebbe ora avere le modifiche che desideri unire nuovamente.
  4. Apportare modifiche o unire questo ramo per sviluppare / padroneggiare
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.