Butta via gli impegni locali a Git


1469

A causa di una cattiva raccolta delle ciliegie, il mio repository Git locale è attualmente cinque commit in anticipo rispetto all'origine e non in buono stato. Voglio liberarmi di tutti questi impegni e ricominciare da capo.

Ovviamente, cancellare la mia directory di lavoro e ripetere la clonazione lo farebbe, ma scaricare di nuovo tutto da GitHub sembra eccessivo, e non è un buon uso del mio tempo.

Forse git revertè quello di cui ho bisogno, ma non voglio finire 10 commit prima dell'origine (o addirittura sei), anche se riporta il codice stesso nello stato giusto. Voglio solo far finta che l'ultima mezz'ora non sia mai avvenuta.

C'è un semplice comando che lo farà? Sembra un ovvio caso d'uso, ma non ne trovo alcun esempio.


Nota che questa domanda riguarda specificamente gli commit , non i seguenti :

  • file non tracciati
  • modifiche non messe in scena
  • modifiche in scena, ma senza commit

Risposte:


2470

Se i tuoi commit in eccesso sono visibili solo a te, puoi semplicemente git reset --hard origin/<branch_name> tornare indietro dove si trova l'origine. Ciò ripristinerà lo stato del repository al commit precedente e annullerà tutte le modifiche locali.

Facendo un git revertrende nuovi commit per rimuovere vecchie impegna in modo da mantenere la storia sana di mente di tutti.


91
git reset --hard <commit hash, branch, or tag>se si desidera andare a un riferimento specifico diverso da un ramo remoto.
Sam Soffes,

55
Per essere chiari, se non stai lavorando mastersu un altro ramo, dovresti correregit reset --hard origin/<your-branch-name>
Zoltán,

33
Questo non solo eliminerà gli commit locali, ma eliminerà anche tutto nella tua struttura di lavoro (es. File locali). Se tutto quello che vogliamo fare è uncommit, ma lasciare intatto il vostro lavoro, si dovrebbe fare "git TESTA Reset ^" ... per stackoverflow.com/questions/2845731/...
aaronbauman

3
Potresti voler fare un recupero dopo questo. Questo risolveva il contatore del numero di commit in attesa di essere spinto su SourceTree.
Stan,

2
git reset --hard origin/<branch_name>Ripristinerà anche la configurazione del progetto, quindi prenditi cura di questo. Ho un .cfgfile di grandi dimensioni che è stato ripristinato ai valori predefiniti. Ho dovuto trascorrere ore di nuovo su questo.
MAC,

271

Basta eliminare il ramo principale locale e ricrearlo in questo modo:

git branch -D master
git checkout origin/master -b master

2
Funziona bene quando il backtracking delle modifiche costerebbe troppo tempo, cosa che mi è successa dopo un paio di ribattezze.
aross

1
Utile per problemi di pull / push tra i membri del team!
Jorge Orpinel,

Questo è perfetto quando si desidera ripristinare un ramo anziché solo il master.
Vladimir Ralev,

1
questo non è un buon modo per eliminare un singolo commit locale. Meglio usaregit reset --hard origin/<branch_name>
Kirit Vaghela il

1
Forse quella soluzione funzionerà, ma ciò non significa che sia quella giusta.
Adly,

202

Provare:

git reset --hard <the sha1 hash>

per reimpostare la testa ovunque tu voglia essere. Usa gitk per vedere a quale commit vuoi essere. Puoi anche resettare da gitk.


5
Ha valutato questo b / c come informazioni utili, ma la risposta di Ben Jackson ottiene il segno di spunta per risolvere esattamente ciò che volevo, in un modo che non mi richiedeva di cercare hash di commit. :)
David Moles,

2
Questo è quello in cui la tua nuova filiale non è ancora stata portata all'origine
gennaio

126

Elimina il commit più recente:

git reset --hard HEAD~1

Elimina il commit più recente, senza distruggere il lavoro svolto:

git reset --soft HEAD~1


5
Risposta utile. Grazie! Ho usato git reset --soft origin / master
Tarun Kumar il

2
@TarunKumar GRAZIE! Sto usando l'integrazione VS e la tua soluzione è stata l'unico modo in cui sono stato in grado di cancellare un sacco di commit di merge che non volevo in un ramo in cui non avevo il permesso di fare il check-in.
DVK

Grazie, proprio quello che stavo cercando, "git reset --soft HEAD ~ 1" ha fatto il lavoro perché mi sono impegnato involontariamente e volevo ripristinare ma avevo altri file che non volevo essere distrutti dopo il ripristino.
edvard_munch,

47

Se si utilizza l' app Atlassian SourceTree , è possibile utilizzare l'opzione di ripristino nel menu di scelta rapida.

inserisci qui la descrizione dell'immagine


42

Nel tentativo di succursale:

git reset --hard origin/<branch_name>

Convalida l'inversione (allo stato, senza commit locali), usando " git log" o " git status" da qui.


1
@Troyseph: tutte le risposte sopra elencate, ho provato così com'è e non ho risolto lo scenario. L'approccio generico, che non è stato illustrato in nessuna delle risposte precedenti, è ciò a cui è stato tentato di rispondere qui.
Parassita

3
La risposta accettato è uguali ai suoi, meno il nome generico ramo, e nei commenti @Zoltan dice esplicitamenteJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph

1
Questa è la migliore risposta secondo me.
dwjohnston,

21

git reset --hard @{u}* elimina tutte le modifiche locali nella filiale corrente, inclusi gli commit. Sono sorpreso che nessuno lo abbia ancora pubblicato considerando che non dovrai cercare quale impegno impegnarti a ripristinare o giocare con i rami.

* Cioè, ripristina il ramo corrente su @{upstream}—monalmente origin/<branchname>, ma non sempre


1
Alcune conchiglie come i pesci interpreteranno "@", quindi potresti dover inserire "@ {u}" tra virgolette, ad esempio "git reset --hard" @ {u} ". Comunque, buona scoperta!
trysis

La risposta eccezionale è fantastica
Marko,

1
Come si stampa il valore di @ {u}?
Philip Rego,

12

Per vedere / ottenere l'id SHA-1 del commit, vuoi tornare anche tu

gitk --all

Per tornare a quel commit

git reset --hard sha1_id

!Nota. Tutti i commit effettuati dopo tale commit verranno eliminati (e tutte le modifiche apportate al progetto). Quindi prima clonare meglio il progetto in un altro ramo o copiarlo in un'altra directory.


questo è ottimo per le situazioni in cui il telecomando non è più disponibile e si deve semplicemente ripristinare un commit locale. gitk è fantastico - non ne ero a conoscenza prima.
theRiley il

Se sei già in gitk, puoi semplicemente fare clic con il tasto destro del mouse sul commit e selezionare "Ripristina ramo XY su qui".
mkrieger1,

E i nuovi commit non verranno immediatamente cancellati. Non c'è più alcun ramo che li punti più (ricorda, un ramo non è altro che un "segnalibro" per un particolare commit).
mkrieger1,

9

Ho avuto una situazione in cui volevo rimuovere un commit che non era stato spinto, ma il commit era prima di un altro. Per fare ciò, ho usato il seguente comando

git rebase -i HEAD~2 -> ribadirà gli ultimi due commit

E ho usato 'drop' per la firma di commit che volevo rimuovere.


9

Rimuovi file non tracciati (modifiche locali senza commit)

git clean -df

Eliminazione permanente di tutti i commit locali e ricezione dell'ultimo commit remoto

git reset --hard origin/<branch_name>

8

Per i commit locali che non vengono inviati, è anche possibile utilizzare git rebase -iper eliminare o annullare un commit.


1
So che questa potrebbe non essere la soluzione più breve, ma ti ho votato perché IMHO git rebase -iè un modo più generico per risolvere molti problemi simili e può essere utile in una varietà di situazioni.
Stefan Marinov,

1
Utilizzare la dropparola chiave (anziché eliminare una riga) quando si rimuovono tutti i commit per evitare l'interruzione del rebase.
Michal Čizmazia,

6

La soluzione semplice sarà quella di abbinare la diramazione principale locale HEAD all'origine / principale ramo HEAD

git reset --hard origin/master

PS: origin / master - è il puntatore remoto al ramo master. Puoi sostituire master con qualsiasi nome di filiale


4

Prima di rispondere, aggiungiamo alcuni retroscena, spiegando di cosa si tratta HEAD. poiché alcune delle opzioni seguenti comporteranno una testa staccata

First of all what is HEAD?

HEADè semplicemente un riferimento al commit corrente (più recente) sul ramo corrente.
Può essercene solo uno HEADin qualsiasi momento. (esclusi igit worktree )

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


detached HEAD

Se non si esegue l'ultimo commit, il che significa che HEADindica un commit precedente nella cronologia che viene chiamato detached HEAD.

inserisci qui la descrizione dell'immagine

Sulla riga di comando, sarà simile al seguente: SHA-1 invece del nome del ramo poiché HEADnon punta alla punta del ramo corrente

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine

Alcune opzioni su come recuperare da una HEAD staccata:


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 verificherà il nuovo ramo che punta al commit desiderato.
Questo comando eseguirà il checkout per un determinato 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 refloganche quello.
git reflogvisualizzerà qualsiasi modifica che ha aggiornato il HEADe il checkout della voce di reflog desiderata HEADriporterà questo commit.

Ogni volta che HEAD viene modificato, ci sarà una nuova voce in reflog

git reflog
git checkout HEAD@{...}

Questo ti riporterà al commit desiderato

inserisci qui la descrizione dell'immagine


git reset --hard <commit_id>

"Sposta" HEAD 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.
  • Nota: ( da Git 2.7 )
    puoi anche usare git rebase --no-autostashanche questo.

git revert <sha-1>

"Annulla" l'intervallo di commit o commit specificato.
Il comando reset "annulla" tutte le modifiche apportate nel commit dato.
Verrà eseguito il commit di un nuovo commit con la patch di annullamento mentre il commit originale rimarrà anche nella cronologia.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Questo schema illustra quale comando fa cosa.
Come puoi vedere, reset && checkoutmodifica il HEAD.

inserisci qui la descrizione dell'immagine


3

Per coloro che sono interessati alla soluzione di Visual Studio, ecco il tutorial:

  1. Nella Team Explorerfinestra, connettersi al repository di destinazione.
  2. Quindi Branches, fai clic con il pulsante destro del mouse sul ramo di interesse e selezionaView history .
  3. Fare clic con il tasto destro del mouse su un commit nella Historyfinestra e scegliere Reset -> Delete changes (--hard).

Ciò eliminerà i tuoi commit locali e resetterà lo stato del tuo repository al commit selezionato. Vale a dire le modifiche dopo aver tirato il repository andranno perse.


2

Se la tua filiale è in anticipo su "origin/XXX ' di 5 commit.

Puoi emettere:

git reset --hard HEAD~5

E dovrebbe rimuovere gli ultimi 5 commit.


0
git reset --hard <SHA-Code>

Questo sarà utile se hai fatto alcuni errori sulla tua copia locale che vuoi assicurarti di non essere spinto per errore nel tuo ramo remoto.

Il codice SHA può essere ottenuto osservando webVersion della dashboard git per l'ultimo commit sul ramo.

In questo modo è possibile sincronizzarsi con l'ultimo commit sul ramo.

Puoi farlo git pulldopo aver completato con successo l'hard reset per confermare nulla di nuovo da sincronizzare, ovvero puoi vedere il messaggio.

La tua filiale è aggiornata con Origin/<Branch Name>


0

Se porti il ​​tuo repository locale in un casino completo, un modo affidabile per buttare via gli commit locali in Git è quello di ...

  1. Usa "git config --get remote.origin.url" per ottenere un URL di origine remota
  2. Rinomina la cartella git locale in "my_broken_local_repo"
  3. Utilizzare "git clone <url_from_1>" per ottenere una nuova copia locale del repository git remoto

Nella mia esperienza, Eclipse gestisce abbastanza bene il mondo che lo circonda. Tuttavia, potrebbe essere necessario selezionare i progetti interessati in Eclipse e pulirli per forzare Eclipse a ricostruirli. Immagino che anche altri IDE potrebbero aver bisogno di una ricostruzione forzata.

Un vantaggio secondario della procedura sopra è che scoprirai se il tuo progetto si basa su file locali che non sono stati messi in git. Se trovi che mancano dei file, puoi copiarli da "my_broken_local_repo" e aggiungerli a git. Una volta che hai la certezza che il tuo nuovo repository locale abbia tutto ciò di cui hai bisogno, puoi eliminare "my_broken_local_repo".


0

Se vuoi semplicemente eliminare gli commit locali e mantenere le modifiche fatte nei file, fai
git reset @ ~
Altre risposte indirizzate al hard reset

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.