Come usare Git Revert


107

Come si git revertusa?

Potrebbe sembrare una domanda duplicata, ma quando le persone la chiedono, la risposta è spesso, utilizzare git resetcome per Ripristinare un commit da un hash SHA in Git?

Quindi, quando qualcuno chiede come usare, le git resetpersone rispondono dicendo che dovresti usare git revertcome per Git - come eseguire il rollback

Prima che tu te ne accorgessi, 8 persone diverse sono apparse con i loro modi unici per salvare il culo dell'OP, tutto sopra la tua testa.

Quindi proviamo a rispettare il brief e a scrivere una guida sui manichini git revert.

Uno scenario: ti sei impegnato due volte per padroneggiarlo e il suo male. Hai spinto e altre persone hanno i tuoi brutti cambiamenti.

Vuoi annullarlo. Non è qualcosa che puoi annullare manualmente nel codice, ad esempio un mago o un gestore di pacchetti ha cambiato tonnellate di cose dappertutto - vuoi solo rimettere tutto a posto come era.

Questo è il controllo del codice sorgente. Sono sicuro che sia facile.

Va bene, lo userai git revertma come?

E dopo aver corso git revertdevi fare qualcos'altro dopo? Devi eseguire il commit delle modifiche ripristinate o ripristinate direttamente il commit nel repository o cosa ??

Ovviamente dovrai spingere di nuovo e probabilmente annunciare le tue palle alla squadra.

Risposte:


119

git revert fa un nuovo commit

git revert crea semplicemente un nuovo commit che è l'opposto di un commit esistente.

Lascia i file nello stesso stato come se il commit che è stato ripristinato non fosse mai esistito. Ad esempio, considera il seguente semplice esempio:

$ cd /tmp/example
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ echo "Initial text" > README.md
$ git add README.md
$ git commit -m "initial commit"
[master (root-commit) 3f7522e] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ echo "bad update" > README.md 
$ git commit -am "bad update"
[master a1b9870] bad update
 1 file changed, 1 insertion(+), 1 deletion(-)

In questo esempio, la cronologia dei commit ha due commit e l'ultimo è un errore. Utilizzando git revert:

$ git revert HEAD
[master 1db4eeb] Revert "bad update"
 1 file changed, 1 insertion(+), 1 deletion(-)

Ci saranno 3 commit nel registro:

$ git log --oneline
1db4eeb Revert "bad update"
a1b9870 bad update
3f7522e initial commit

Quindi c'è una cronologia coerente di ciò che è successo, ma i file sono come se l'aggiornamento non corretto non fosse mai avvenuto:

cat README.md 
Initial text

Non importa dove si trovi nella cronologia il commit da annullare (nell'esempio sopra, l'ultimo commit viene annullato - qualsiasi commit può essere annullato).

Domande conclusive

devi fare qualcos'altro dopo?

A git revertè solo un altro commit, quindi ad es. Push al telecomando in modo che altri utenti possano estrarre / recuperare / unire le modifiche e il gioco è fatto.

Devi eseguire il commit delle modifiche ripristinate o il ripristino viene eseguito direttamente sul repository?

git revert è un commit: non ci sono passaggi aggiuntivi supponendo che il ripristino di un singolo commit sia ciò che si desidera fare.

Ovviamente dovrai spingere di nuovo e probabilmente annunciare alla squadra.

In effetti, se il telecomando è in uno stato instabile, comunicare al resto del team che devono eseguire il pull per ottenere la correzione (il commit di ripristino) sarebbe la cosa giusta da fare :).


A titolo di conferma, sia per la prima affermazione qui che per chiunque si chieda la stessa cosa che mi chiedevo su come funziona, puoi ripristinare un ripristino, dove ci sono diversi nuovi commit dal ripristino che stai ripristinando. Quindi il ripristino è davvero solo un commit dell'opposto del commit ripristinato. Potresti, ovviamente, avere dei conflitti ... ma questa è una storia diversa.
GG2

Trovo sempre meglio evitare di impegnarmi con esso, solo per rivedere prima le modifiche e io uso, git revert -n <commitToRevet> oppure git revert --no-commit <commitToRevet>
Eklavyaa

2
Volevo solo dire che dopo anni su stackoverflow, penso che questa potrebbe essere una delle migliori risposte che abbia mai incontrato. Ottimo esempio e spiegazione Grazie.
user3344977

Sono entrato qui aspettandomi di ottenere maggiori informazioni, qualcosa come un TLDR di questo raw.githubusercontent.com/git/git/master/Documentation/howto/…
wviana

1
@wviana Se le informazioni che hai trovato non sono sufficienti, scrivi una risposta. Nota che lo stack overflow non sostituisce la documentazione ufficiale (a cui sembra che ti colleghi e copre un ambito molto più ampio di questa domanda).
AD7six

35

Usa git revert in questo modo:

git revert <insert bad commit hash here>

git revertcrea un nuovo commit con le modifiche di cui viene eseguito il rollback. git resetcancella la tua cronologia git invece di fare un nuovo commit.

I passaggi successivi sono gli stessi di qualsiasi altro commit.


La differenza tra "ripristinare un commit" e "ripristinare un commit" è abbastanza sottile che ho lottato con questo comando per anni. La tua spiegazione mi ha risolto immediatamente. Grazie!
Claviska

24

Il motivo resete la reverttendenza a emergere spesso nelle stesse conversazioni è perché diversi sistemi di controllo delle versioni li usano per significare cose diverse.

In particolare, le persone che sono abituate a SVN o P4 che vogliono buttare via le modifiche non salvate a un file spesso raggiungeranno revertprima che gli venga detto che lo vogliono effettivamente reset.

Allo stesso modo, l' revertequivalente in altri VCS viene spesso chiamato rollbacko qualcosa di simile - ma "rollback" può anche significare "Voglio eliminare completamente gli ultimi commit", il che è appropriato resetma non lo è revert. Quindi, c'è molta confusione dove le persone sanno cosa vogliono fare, ma non sono chiari su quale comando dovrebbero usare per questo.

Per quanto riguarda le tue reali domande sul ripristino ...

Ok, userai git revert ma come?

git revert first-bad-commit..last-bad-commit

E dopo aver eseguito git revert devi fare qualcos'altro dopo? Devi eseguire il commit delle modifiche ripristinate o ripristinate direttamente il commit nel repository o cosa ??

Per impostazione predefinita, git revertrichiede un messaggio di commit e quindi esegue il commit dei risultati. Questo può essere ignorato. Cito la pagina man :

--modificare

Con questa opzione, git revert ti consentirà di modificare il messaggio di commit prima di eseguire il commit del ripristino. Questa è l'impostazione predefinita se esegui il comando da un terminale.

--no-commit

Di solito il comando crea automaticamente alcuni commit con messaggi di log dei commit che indicano quali commit sono stati annullati. Questo flag applica le modifiche necessarie per ripristinare i commit nominati all'albero di lavoro e all'indice, ma non esegue i commit. Inoltre, quando viene utilizzata questa opzione, il tuo indice non deve corrispondere al commit HEAD. Il ripristino viene eseguito rispetto allo stato iniziale del tuo indice.

Ciò è utile quando si ripristina più di un effetto di commit sull'indice di seguito.

In particolare, per impostazione predefinita crea un nuovo commit per ogni commit che stai ripristinando. È possibile utilizzare revert --no-commitper creare modifiche ripristinandole tutte senza eseguire il commit di tali modifiche come commit individuali, quindi eseguire il commit a proprio piacimento.


git revert first-bad-commit..last-bad-commit: Penso che dovrebbe essere git revert parent-of-first-bad-commit..last-bad-commit.
user1071847

9

La domanda è piuttosto vecchia ma il ripristino continua a confondere le persone (come me)

Come principiante, dopo alcuni tentativi ed errori (più errori che tentativi) ho un punto importante:

  • git revertrichiede l'id del commit che desideri rimuovere mantenendolo nella tua cronologia

  • git resetrichiede il commit che desideri mantenere e, di conseguenza, rimuoverà qualsiasi cosa dalla cronologia.

Cioè, se usi revertcon il primo id commit, ti ritroverai in una directory vuota e un commit aggiuntivo nella cronologia, mentre con reset la tua directory verrà .. ripristinata al commit iniziale e la tua cronologia diventerà come se gli ultimi commit non sono mai avvenuti.

Per essere ancora più chiari, con un registro come questo:

# git log --oneline

cb76ee4 wrong
01b56c6 test
2e407ce first commit

Utilizzando git revert cb76ee4volontà di default portare i file di nuovo a 01b56c6 e aggiungerà un ulteriore impegno per la vostra storia:

8d4406b Revert "wrong"
cb76ee4 wrong
01b56c6 test
2e407ce first commit

git reset 01b56c6 riporterà invece i tuoi file a 01b56c6 e ripulirà qualsiasi altro commit successivo dalla tua cronologia:

01b56c6 test
2e407ce first commit

So che queste sono "le basi" ma è stato abbastanza confuso per me, eseguendo revertil primo id ('primo commit') mi aspettavo di trovare i miei file iniziali, ci è voluto un po 'per capire che se hai bisogno dei tuoi file indietro come 'primo commit' devi usare l'id successivo.


Ho osservato lo stesso. è davvero confuso ma così importante da sapere. di recente ho dovuto aiutare un collega e me ne sono dimenticato. È stato un po 'imbarazzante.
ExOfDe

1

Ho ripristinato alcuni commit eseguendo 'git revert commit id' come:

git revert b2cb7c248d416409f8eb42b561cbff91b0601712

Quindi mi è stato chiesto di eseguire il commit del ripristino (proprio come faresti quando esegui "git commit"). Il mio programma terminale predefinito è Vim, quindi ho eseguito:

:wq 

Alla fine ho inviato la modifica al repository con:

git push
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.