Qualcuno sa come annullare facilmente un rebase git?
L'unico modo che mi viene in mente è quello di farlo manualmente:
Nella mia situazione attuale questo funzionerà perché posso facilmente individuare i commit da entrambi i rami (uno era roba mia, l'altro era roba del mio collega).
Tuttavia il mio approccio mi sembra subottimale e soggetto a errori (diciamo che avevo appena fatto il rebased con 2 rami miei).
Qualche idea?
Chiarimento: Sto parlando di un rebase durante il quale un mucchio di commit sono stati riprodotti. Non solo uno.
Il modo più semplice sarebbe trovare l'head commit del ramo come era immediatamente prima che il rebase iniziasse nel reflog...
git reflog
e resettare il ramo corrente su di esso (con i soliti avvertimenti sull'essere assolutamente sicuri prima di resettare con l'opzione --hard
).
Supponiamo che il vecchio commit sia HEAD@{5}
nel log del ref:
git reset --hard HEAD@{5}
In Windows, potrebbe essere necessario citare il riferimento:
git reset --hard "HEAD@{5}"
Puoi controllare la storia della vecchia testa candidata facendo semplicemente un git log HEAD@{5}
(Windows: git log "HEAD@{5}"
).
Se non hai disabilitato i reflog per ramo, dovresti essere in grado di fare semplicemente git reflog branchname@{1}
poiché un rebase stacca la testa del ramo prima di riattaccarla alla testa finale. Vorrei ricontrollare questo, anche se non l'ho verificato di recente.
Per impostazione predefinita, tutti i reflog sono attivati per i repository non spogli:
[core]
logAllRefUpdates = true
Resettare il ramo all'oggetto commit dangling della sua vecchia punta è ovviamente la soluzione migliore, perché ripristina lo stato precedente senza spendere alcuno sforzo. Ma se ti capita di aver perso quei commit (ad esempio perché nel frattempo hai raccolto spazzatura nel tuo repository, o questo è un clone fresco), puoi sempre rifare il rebase del ramo di nuovo. La chiave di questo è l'interruttore -onto
.
Diciamo che hai un ramo tematico immaginariamente chiamato topic
, che hai ramificato da master
quando la punta di master
era il commit 0deadbeef
. Ad un certo punto, mentre eri sul ramo topic
, hai fatto git rebase master
. Ora vuoi annullare questo. Ecco come:
git rebase --onto 0deadbeef master topic
Questo prenderà tutti i commit su topic
che non sono su master
e li riprodurrà su 0deadbeef
.
Con --onto
, puoi riorganizzare la tua cronologia praticamente in qualsiasi forma.
Divertiti;
Per i commit multipli, ricordate che ogni commit fa riferimento a tutta la storia che porta a quel commit. Quindi, nella risposta di Charles, leggi "il vecchio commit" come "il più recente dei vecchi commit". Se si resetta a quel commit, allora tutta la storia che porta a quel commit riapparirà. Questo dovrebbe fare ciò che vuoi.