versione - git tutorial ita




Come ripristinare un repository Git su un commit precedente (20)

Come faccio a tornare dal mio stato attuale a uno scatto fatto su un certo commit?

Se faccio git log , ottengo il seguente risultato:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <[email protected]>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <[email protected]>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <[email protected]>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <[email protected]>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Come ripristinare il commit dal 3 novembre, ovvero commit 0d1d7fc ?


Attenzione! Questo comando può causare la perdita della cronologia del commit, se l'utente inserisce erroneamente il commit errato. Hai sempre un backup extra del tuo git, dove altro, nel caso in cui tu faccia degli errori, allora sei un po 'più sicuro. :)

Ho avuto un problema simile e volevo tornare al precedente Commit. Nel mio caso non sono stato intestato per mantenere il commit più recente, quindi ho usato Hard.

Ecco come l'ho fatto:

git reset --hard CommitId && git clean -f

Questo verrà ripristinato sul repository locale, qui dopo l'utilizzo git push -fverrà aggiornato il repository remoto.

git push -f

Alternative extra alle soluzioni di Jefromi

Le soluzioni di Jefromi sono sicuramente le migliori e dovresti sicuramente usarle. Tuttavia, per completezza, volevo anche mostrare queste altre soluzioni alternative che possono essere utilizzate anche per ripristinare un commit (nel senso che crei un nuovo commit che annulla le modifiche nel commit precedente , proprio come fa git revert ) .

Per essere chiari, queste alternative non sono il modo migliore per ripristinare i commit , le soluzioni di Jefromi lo sono , ma voglio solo sottolineare che puoi anche usare questi altri metodi per ottenere la stessa funzione di git revert .

Alternativa 1: Ripristini rigidi e morbidi

Questa è una versione leggermente modificata della soluzione di Charles Bailey per Revert to a commit di un hash SHA in Git? :

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft [email protected]{1}

# Commit the changes
git commit -m "Revert to <commit>"

Questo funziona fondamentalmente usando il fatto che le reimpostazioni software lasceranno lo stato del commit precedente messo a punto nell'indice / area di staging, che è quindi possibile eseguire il commit.

Alternativa 2: Elimina l'albero corrente e sostituisci con quello nuovo

Questa soluzione proviene dalla soluzione di svick al vecchio commit di Checkout e ne fa un nuovo commit :

git rm -r .
git checkout <commit> .
git commit

Analogamente al numero 1 alternativo, questo riproduce lo stato di <commit> nella copia di lavoro corrente. È necessario eseguire prima git rm perché git checkout non rimuoverà i file che sono stati aggiunti da <commit> .


Ripristino della copia di lavoro in commit più recente

Per ripristinare un commit precedente, ignorando eventuali modifiche:

git reset --hard HEAD

dove HEAD è l'ultimo commit nel tuo attuale ramo

Ripristino della copia di lavoro in un commit precedente

Per ripristinare un commit più vecchio del commit più recente:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft [email protected]{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

I crediti vanno a una domanda simile di , Ripristina un commit da un hash SHA in Git? .


È possibile completare personalmente tutti questi passaggi iniziali e tornare a git repo.

  1. Estrai l'ultima versione del tuo repository da Bitbucket usando il comando git pull --all .

  2. Esegui il comando git log con -n 4 dal tuo terminale. Il numero dopo -n determina il numero di commit nel registro a partire dal commit più recente nella cronologia locale.

    $ git log -n 4

  3. Reimposta la cronologia della cronologia del tuo repository usando git reset --hard HEAD~N dove N è il numero di commit che vuoi recuperare. Nell'esempio seguente, la testa dovrebbe essere impostata su un commit, sull'ultimo commit nella cronologia del repository:

  4. Spingi la modifica a git repo usando git push --force per forzare la modifica.

Se vuoi git repository ad un commit precedente

git pull --all
git reset --hard HEAD~1
git push --force

Dopo tutte le modifiche, quando si preme tutti questi comandi, potrebbe essere necessario utilizzare:

git push -f ...

E non solo git push .


Ecco un modo molto più semplice per tornare a un commit precedente (e averlo in uno stato non limitato, per fare ciò che vuoi):

git reset HEAD~1

Quindi, non c'è bisogno di ID di commit e così via :)


Ho provato un sacco di modi per ripristinare le modifiche locali in Git, e sembra che funzioni meglio se si desidera ripristinare lo stato di commit più recente.

git add . && git checkout master -f

Breve descrizione:

  • NON creerà alcun commit come fa git revert .
  • NON staccherà il tuo HEAD come git checkout <commithashcode> .
  • Sostituirà tutte le modifiche locali e CANCELLERÀ tutti i file aggiunti dall'ultimo commit nel ramo.
  • Funziona solo con i nomi dei rami, quindi puoi ripristinare solo l'ultimo commit nel ramo in questo modo.

Ho trovato un modo molto più conveniente e semplice per ottenere i risultati sopra:

git add . && git reset --hard HEAD

dove HEAD punta all'ultima commit al tuo attuale ramo.

È lo stesso codice codice suggerito da boulder_ruby, ma ho aggiunto git add . prima di git reset --hard HEAD per cancellare tutti i nuovi file creati dall'ultimo commit poiché questo è ciò che la maggior parte delle persone si aspetta che io creda quando si ripristina l'ultimo commit.


L'opzione migliore per me e probabilmente altri è l'opzione di ripristino Git:

git reset --hard <commidId> && git clean -f

Questa è stata l'opzione migliore per me! È semplice, veloce ed efficace!

Nota: come menzionato nei commenti, non farlo se condividi il tuo ramo con altre persone che hanno copie dei vecchi commit

Anche dai commenti, se volessi usare un metodo meno "ballzy"

git clean -i


Niente qui ha funzionato per me oltre a questa combinazione esatta:

git reset --hard <commit_hash>
git push origin <branch_name> --force

La chiave qui è forzare la spinta, nessun commit aggiuntivo / messaggi di commit ecc.


Per mantenere le modifiche dal commit precedente a HEAD e passare al commit precedente, fai:

git reset <SHA>

Se le modifiche non sono richieste dal precedente commit a HEAD e semplicemente scartare tutte le modifiche, fare:

git reset --hard <SHA>

Prima di rispondere aggiungiamo un po 'di background, spiegando cos'è questo HEAD .

First of all what is HEAD?

HEAD è semplicemente un riferimento al commit corrente (più recente) sul ramo corrente. Può esserci un solo HEAD in qualsiasi momento (escluso l' git worktree ).

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

detached HEAD

Se non si è sul commit più recente - significa che HEAD punta a un commit precedente nella cronologia è chiamato detached HEAD .

Sulla riga di comando sarà simile a questo: SHA-1 invece del nome del ramo poiché HEAD non punta al tip del ramo corrente:

Alcune opzioni su come recuperare da un HEAD distaccato:

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 controllerà il nuovo ramo che punta al commit desiderato. Questo comando eseguirà il checkout su un dato 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 anche il reflog . git reflog visualizzerà tutte le modifiche che hanno aggiornato l' HEAD e verificando la voce di reflog desiderata imposterà il HEAD su questo commit.

Ogni volta che l'HEAD viene modificato ci sarà una nuova voce nel reflog

git reflog
git checkout [email protected]{...}

Questo ti riporterà al commit desiderato

git reset HEAD --hard <commit_id>

"Sposta" la testa 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.

Questo schema illustra quale comando fa cosa. Come puoi vedere, il reset && checkout modificano l' HEAD .


Puoi farlo con i seguenti due comandi:

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

Rimuoverà il tuo precedente commit Git.

Se vuoi mantenere le tue modifiche, puoi anche usare:

git reset --soft [previous Commit SHA id here]

Quindi salverà le tue modifiche.


Revert è il comando per il rollback dei commit.

git revert <commit1> <commit2> 

Campione:

git revert 2h3h23233

È in grado di prendere distanza dal TESTO come di seguito. Qui 1 dice "ripristina l'ultimo commit".

git revert HEAD~1..HEAD

e poi fai git push


Ripristina il commit più recente e ignora tutte le modifiche locali:

git reset --hard HEAD

Se vuoi "uncommit", cancella l'ultimo messaggio di commit e rimetti i file modificati nella staging, dovresti usare il comando:

git reset --soft HEAD~1
  • --soft indica che i file non salvati dovrebbero essere mantenuti come file di lavoro opposti a --hard che li eliminerebbe.
  • HEAD~1 è l'ultimo commit. Se si desidera eseguire il rollback di 3 commit, è possibile utilizzare HEAD~3 . Se si desidera eseguire il rollback a un numero di revisione specifico, è possibile farlo utilizzando l'hash SHA.

Questo è un comando estremamente utile in situazioni in cui hai commesso la cosa sbagliata e vuoi annullare quell'ultimo commit.

Fonte: http://nakkaya.com/2009/09/24/git-delete-last-commit/


Seleziona il commit richiesto e controllalo

git show HEAD
git show HEAD~1
git show HEAD~2 

fino a ottenere il commit richiesto. Per fare in modo che la TESTA indichi ciò, fallo

git reset --hard HEAD~1

o git reset --hard HEAD~2 o qualsiasi altra cosa.


Supponiamo che tu abbia il seguente commit in un file di testo chiamato ~/commits-to-revert.txt (ho usato git log --pretty=oneline per ottenerli)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Crea uno script di shell Bash per annullare ciascuno di essi:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

Ciò ripristina tutto allo stato precedente, incluse le creazioni di file e directory e le eliminazioni, lo inoltra al ramo e si conserva la cronologia, ma viene ripristinata nella stessa struttura di file. Perché Git non ha un git revert --to <hash> è oltre me.


OK, tornare al precedente commit in git è abbastanza facile ...

Ritornare indietro senza mantenere le modifiche:

git reset --hard <commit>

Ritornare indietro mantenendo le modifiche:

git reset --soft <commit>

Spiega: utilizzando git reset, puoi ripristinare uno stato specifico, è comune utilizzarlo con un hash di commit come vedi sopra.

Ma come vedi la differenza sta usando i due flag --soft e --hard , per impostazione predefinita git reset usando --soft flag, ma è una buona pratica usare sempre il flag, spiego ogni flag:

--soft

Il flag predefinito come spiegato, non è necessario fornirlo, non modifica l'albero di lavoro, ma aggiunge tutti i file di modifiche pronti per il commit, quindi si torna allo stato di commit che non viene disattivato.

--difficile

Fai attenzione a questo flag, resetta l'albero di lavoro e tutte le modifiche ai file tracciati e tutto sarà sparito!

Ho anche creato l'immagine qui sotto che può capitare in una vita reale lavorando con git:


Prova a resettare il commit desiderato -

git reset <COMMIT_ID>

(per controllare l'uso di COMMIT_ID git log)

Ciò ripristinerà tutti i file modificati in stato non aggiunto.

Ora puoi checkouttutti i file non aggiunti da

git checkout .

Verifica git logper verificare le tue modifiche.

AGGIORNARE

Se ne hai uno e commetti solo nel tuo repository, prova

git update-ref -d HEAD


Poiché i tuoi commit vengono spinti da remoto, devi rimuoverli. Consentitemi di assumere che il vostro ramo si sviluppi e che venga spinto sull'origine.

Devi prima rimuovere lo sviluppo dall'origine:

git push origin :develop (note the colon)

Quindi devi sviluppare lo stato desiderato, lascia che l'hash del commit sia EFGHIJK:

git reset --hard EFGHIJK

Infine, spingere sviluppare nuovamente:

git push origin develop




git-revert