Ricerca…
Annullare le fusioni
Annullamento di un'unione non ancora inviata a un remoto
Se non hai ancora trasferito l'unione nel repository remoto, puoi seguire la stessa procedura di annullare il commit anche se ci sono alcune sottili differenze.
Un ripristino è l'opzione più semplice in quanto annulla sia il commit di unione che qualsiasi commit aggiunto dal ramo. Tuttavia, sarà necessario sapere a quale SHA resettare, questo può essere complicato dato che il git log
mostrerà i commit da entrambe le diramazioni. Se si ripristina il commit sbagliato (ad esempio uno sull'altro ramo) può distruggere il lavoro impegnato.
> git reset --hard <last commit from the branch you are on>
Oppure, supponendo che l'unione fosse il tuo commit più recente.
> git reset HEAD~
Un ripristino è più sicuro, in quanto non distruggerà il lavoro impegnato, ma richiede più lavoro in quanto è necessario ripristinare il ripristino prima di poter unire nuovamente il ramo nuovamente (vedere la sezione successiva).
Annullamento di un'unione inviata a un remoto
Supponi di fonderti in una nuova funzione (add-gremlins)
> git merge feature/add-gremlins
...
#Resolve any merge conflicts
> git commit #commit the merge
...
> git push
...
501b75d..17a51fd master -> master
Successivamente si scopre che la funzione appena incorporata ha rotto il sistema per altri sviluppatori, deve essere annullata immediatamente e la correzione della funzionalità stessa richiederà troppo tempo, quindi è sufficiente annullare l'unione.
> git revert -m 1 17a51fd
...
> git push
...
17a51fd..e443799 master -> master
A questo punto i gremlins sono fuori dal sistema e i tuoi colleghi sviluppatori hanno smesso di urlarti contro. Tuttavia, non abbiamo ancora finito. Una volta risolto il problema con la funzione add-gremlins, dovrai annullare questo ripristino prima di poter unire nuovamente.
> git checkout feature/add-gremlins
...
#Various commits to fix the bug.
> git checkout master
...
> git revert e443799
...
> git merge feature/add-gremlins
...
#Fix any merge conflicts introduced by the bug fix
> git commit #commit the merge
...
> git push
A questo punto la tua funzione è ora aggiunta con successo. Tuttavia, dato che i bug di questo tipo sono spesso introdotti dai conflitti di merge, un flusso di lavoro leggermente diverso è talvolta più utile in quanto consente di correggere il conflitto di unione sul ramo.
> git checkout feature/add-gremlins
...
#Merge in master and revert the revert right away. This puts your branch in
#the same broken state that master was in before.
> git merge master
...
> git revert e443799
...
#Now go ahead and fix the bug (various commits go here)
> git checkout master
...
#Don't need to revert the revert at this point since it was done earlier
> git merge feature/add-gremlins
...
#Fix any merge conflicts introduced by the bug fix
> git commit #commit the merge
...
> git push
Usando il reflog
Se rovini un rebase, un'opzione per ricominciare è tornare al commit (prebase). Puoi farlo usando reflog
(che ha la cronologia di tutto ciò che hai fatto negli ultimi 90 giorni - questo può essere configurato):
$ git reflog
4a5cbb3 HEAD@{0}: rebase finished: returning to refs/heads/foo
4a5cbb3 HEAD@{1}: rebase: fixed such and such
904f7f0 HEAD@{2}: rebase: checkout upstream/master
3cbe20a HEAD@{3}: commit: fixed such and such
...
Puoi vedere il commit prima che il rebase fosse HEAD@{3}
(puoi anche eseguire il checkout dell'hash):
git checkout HEAD@{3}
Ora crei un nuovo ramo / cancella quello vecchio / prova di nuovo il rebase.
Puoi anche ripristinare direttamente un punto del tuo reflog
, ma fallo solo se sei sicuro al 100% che è quello che vuoi fare:
git reset --hard HEAD@{3}
Questo imposterà il tuo albero git attuale in modo che corrisponda a come si trovava in quel punto (vedi Annullare le modifiche).
Questo può essere usato se stai vedendo temporaneamente come funziona un ramo quando viene rebasato su un altro ramo, ma non vuoi mantenere i risultati.
Torna a un commit precedente
Per tornare a un commit precedente, prima trova l'hash del commit usando git log
.
Per tornare temporaneamente a quel commit, staccare la testa con:
git checkout 789abcd
Questo ti mette su commit 789abcd
. Ora puoi eseguire nuovi commit su questo vecchio commit senza intaccare il ramo su cui si trova la tua testa. Eventuali modifiche possono essere apportate in un ramo corretto utilizzando uno dei branch
o il checkout -b
.
Per ripristinare un commit precedente mantenendo le modifiche:
git reset --soft 789abcd
Per ripristinare l' ultimo commit:
git reset --soft HEAD~
Per eliminare in modo permanente le modifiche apportate dopo uno specifico commit, utilizzare:
git reset --hard 789abcd
Per eliminare in modo permanente le modifiche apportate dopo l' ultimo commit:
git reset --hard HEAD~
Attenzione: mentre puoi recuperare i commit scartati usando reflog
e reset
, le modifiche non salvate non possono essere recuperate. Usa git stash; git reset
invece di git reset --hard
da essere sicuro.
Annullamento delle modifiche
Annullare le modifiche a un file o a una directory nella copia di lavoro .
git checkout -- file.txt
Utilizzato su tutti i percorsi di file, in modo ricorsivo dalla directory corrente, annulla tutte le modifiche nella copia di lavoro.
git checkout -- .
Per annullare solo parti delle modifiche usa --patch
. Ti verrà chiesto, per ogni modifica, se dovrebbe essere annullato o meno.
git checkout --patch -- dir
Per annullare le modifiche aggiunte all'indice .
git reset --hard
Senza il flag --hard
questo eseguirà un soft reset.
Con i commit locali che devi ancora premere su un telecomando puoi anche eseguire un soft reset. È quindi possibile rielaborare i file e quindi i commit.
git reset HEAD~2
L'esempio sopra riportato svolgerà i tuoi ultimi due commit e restituirà i file alla tua copia di lavoro. Potresti quindi apportare ulteriori modifiche e nuovi commit.
Attenzione: tutte queste operazioni, a parte i soft reset, cancelleranno definitivamente le modifiche. Per un'opzione più sicura, usa git stash -p
o git stash
, rispettivamente. Puoi in seguito annullare con stash pop
o cancellare per sempre con stash drop
.
Ripristina alcuni commit esistenti
Usa git revert per ripristinare i commit esistenti, specialmente quando quei commit sono stati trasferiti su un repository remoto. Registra alcuni nuovi commit per invertire l'effetto di alcuni commit precedenti, che puoi spingere in modo sicuro senza riscrivere la cronologia.
Non utilizzare git push --force
meno che non si desideri abbattere l'opprobrio di tutti gli altri utenti di quel repository. Non riscrivere mai la storia pubblica.
Se, ad esempio, hai appena inserito un commit che contiene un bug e devi eseguirne il backup, procedi come segue:
git revert HEAD~1
git push
Ora sei libero di annullare il ripristino locale, correggere il codice e inserire il codice corretto:
git revert HEAD~1
work .. work .. work ..
git add -A .
git commit -m "Update error code"
git push
Se il commit che desideri annullare è già più indietro nella cronologia, puoi semplicemente passare l'hash del commit. Git creerà un contro-commit che annulla il commit originale, che puoi inviare al tuo telecomando in sicurezza.
git revert 912aaf0228338d0c8fb8cca0a064b0161a451fdc
git push
Annulla / Ripristina una serie di commit
Supponi di voler annullare una dozzina di commit e vuoi solo alcuni di essi.
git rebase -i <earlier SHA>
-i mette rebase in "modalità interattiva". Inizia come il rebase discusso in precedenza, ma prima di ripetere qualsiasi commit, si interrompe e consente di modificare delicatamente ogni commit mentre viene riprodotto. rebase -i
si aprirà nel tuo editor di testo predefinito, con un elenco di commit applicati, come questo:
Per eliminare un commit, elimina quella riga nel tuo editor. Se non desideri più i cattivi commit nel tuo progetto, puoi cancellare le righe 1 e 3-4 sopra. Se vuoi combinare due commit insieme, puoi usare i comandi squash
o fixup