Come ripristinare un commit merge già inserito nel ramo remoto?

git revert da solo non funzionerà. -m deve essere specificato, e sono piuttosto confuso a riguardo.

Qualcuno ha provato questo prima?

L’opzione -m specifica il numero genitore . Ciò è dovuto al fatto che un commit di unione ha più di un genitore e Git non riconosce automaticamente quale padre era la linea principale e quale padre era il ramo che si desidera separare.

Quando visualizzi un merge commit nell’output di git log , vedrai i suoi genitori elencati sulla riga che inizia con Merge :

 commit 8f937c683929b08379097828c8a04350b9b8e183 Merge: 8989ee0 7c6b236 Author: Ben James  Date: Wed Aug 17 22:49:41 2011 +0100 Merge branch 'gh-pages' Conflicts: README 

In questa situazione, git revert 8f937c6 -m 1 ti porterà l’albero come era in 8989ee0 , e git revert -m 2 ripristinerà l’albero come era in 7c6b236 .

Per capire meglio l’ID genitore, puoi eseguire:

 git log 8989ee0 

e

 git log 7c6b236 

Ecco un esempio completo nella speranza che aiuti qualcuno:

 git revert -m 1  git commit -m "Reverting the last commit which messed the repo." git push -u origin master 

Dove è l’hash di commit dell’unione che vorresti ripristinare, e come indicato nella spiegazione di questa risposta , -m 1 indica che desideri tornare all’albero del primo genitore prima di l’unione.

La git commit ... line essenzialmente impegna le modifiche mentre la terza riga rende pubbliche le modifiche spingendole al ramo remoto.

Ben ti ha detto come ripristinare un commit di merge, ma è molto importante rendersi conto che così facendo “dichiara che non vorrai mai che le modifiche dell’albero vengano apportate dall’unione. Di conseguenza, le unioni successive porteranno solo le modifiche dell’albero introdotte da commette che non sono antenati della fusione precedentemente ripristinata, ma potrebbe essere o non essere quello che vuoi. ” (pagina man di git-merge) .

Un messaggio di articolo / mailing list collegato alla pagina man descrive i meccanismi e le considerazioni che sono coinvolti. Assicurati solo di capire che se ripristini il commit unione, non puoi semplicemente unire nuovamente il ramo più tardi e aspettarti che le stesse modifiche ritornino.

È ansible seguire questi passaggi per ripristinare i commit non corretti o ripristinare il ramo remoto per correggere HEAD / stato.

  1. controlla il ramo remoto al repository locale.
    git checkout development
  2. copia l’hash del commit (cioè id del commit immediatamente prima del commit sbagliato) da git log git log -n5

    produzione:

    commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 “Unisci ramo ‘commit-wrong’ in ‘sviluppo'”
    commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 “questo è un commit sbagliato”
    commit 3779ab50e72908da92d2cfcd72256d7a09f446ba “questo è il commit corretto”

  3. reimposta il ramo sull’hash del commit copiato nel passaggio precedente
    git reset (ie 3779ab50e72908da92d2cfcd72256d7a09f446ba)

  4. eseguire lo git status per mostrare tutte le modifiche che facevano parte del commit sbagliato.
  5. semplicemente eseguire git reset --hard per ripristinare tutte quelle modifiche.
  6. forza-spinge il ramo locale a distanza e nota che la cronologia dei commit è pulita come prima che venisse inquinata.
    git push -f origin development
 git revert -m 1  

A volte il modo più efficace per eseguire il rollback è di fare un passo indietro e sostituire.

git log

Usa il secondo hash di commit (hash completo, quello a cui vuoi tornare, prima dell’errore elencato) e poi riorganizza da lì.

git checkout -b newbranch

Quindi elimina il vecchio ramo, copia il newbranch al suo posto e ricomincia da lì.

 git branch -D oldbranch git checkout -b oldbranch newbranch 

Se è stato trasmesso, elimina il vecchio ramo da tutti i repository, sposta il ramo rifatto nel punto più centrale e riportalo a tutti.

Per mantenere il registro pulito come non è successo nulla (con alcuni aspetti negativi con questo approccio (a causa di push -f)):

 git checkout  git reset --hard  git push -f origin HEAD: 

‘commit-hash-before-merge’ viene dal log (git log) dopo l’unione.

Ho trovato la creazione di una patch inversa tra due endpoint noti e l’applicazione di tale patch avrebbe funzionato. Questo presuppone che tu abbia creato istantanee (tag) al di fuori del tuo ramo principale o persino un back up del tuo ramo master, dire master_bk_01012017.

Di ‘il ramo del codice che hai unito in master era mycodebranch.

  1. Checkout master.
  2. Creare una patch inversa binaria completa tra master e il backup. git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. Controlla la patch git apply --check myrevert.patch
  4. Applica patch con firma git am --signoff < myrevert.patch
  5. Se sarà necessario inserire nuovamente questo codice una volta risolto, sarà necessario git branch mycodebranch_fix il master ripristinato e verificare il ramo git branch mycodebranch_fix git checkout mycodebranch_fix
  6. Qui è necessario trovare il tasto SHA per il ripristino e ripristinare il ripristino git revert [SHA]
  7. Ora puoi usare il tuo mycodebranch_fix per correggere i problemi, commetterli e ri-unirmi in master una volta fatto.

Come ha detto Ryan, git revert potrebbe rendere la fusione difficile lungo la strada, quindi git revert potrebbe non essere quello che vuoi. Ho trovato che usare il comando git reset --hard per essere più utile qui.

Una volta eseguita la parte di hard reset, è ansible forzare la push al ramo remoto, ovvero git push -f , dove è spesso denominato origin . Da quel punto puoi ri-unire se vuoi.