2010-10-20 7 views
49

Ho appena inviato la fonte sbagliata al mio progetto utilizzando l'opzione --force.Come posso recuperare da un errato git push -f origine master?

È possibile annullare? Capisco che tutti i rami precedenti sono stati sovrascritti usando l'opzione -f, quindi potrei aver rovinato le mie precedenti revisioni.

+0

possibile duplicato di [È comunque possibile annullare git push -f?] (Http://stackoverflow.com/questions/14476236/is-there-anyway-to-undo-git- push-f) – cmbuckley

risposta

32

Generalmente Git non getta via nulla, ma recuperare da questo può essere ancora complicato.

Se si dispone della sorgente corretta, è sufficiente inserirla nel telecomando con l'opzione --force. Git non avrà cancellato alcuna succursale a meno che tu non glielo abbia detto. Se hai effettivamente perso i commit, dai uno sguardo allo this useful guide to recovering commits. Se conosci lo SHA-1 dei commit che vuoi, allora probabilmente stai bene.

La cosa migliore da fare: eseguire il backup di tutto e vedere ciò che è ancora nel repository locale. Fai lo stesso sul telecomando, se possibile. Utilizzare git fsck per vedere se è possibile ripristinare le cose e, soprattutto, NON eseguire git gc.

Soprattutto, non utilizzare mai l'opzione --force a meno che non lo si intenda davvero.

+37

Probabilmente è sufficiente guardare i diagrammi per determinare dove erano originariamente i rami remoti. Ad esempio, 'git reflog show remotes/origin/master'. Dovresti essere in grado di vedere la tua spinta lì dentro; il commit nella riga precedente è dove si trovava prima che l'avessi incasinato. Puoi quindi semplicemente spingere quella revisione (con '--force') all'origine e tornare dove sei stato! – Cascabel

+0

@David: Oh. Non hai menzionato nella tua domanda che non hai avuto il repository. (Questo è ovviamente qualcosa che non si vuole mai fare.) Se si ha accesso al filesystem dove si è spinto, si può comunque fare tutto ciò lì. – Cascabel

+1

@David: Yikes. È sempre utile avere la directory corrente come parte del prompt per evitare questo genere di cose. – Cascabel

2

Ho fatto la stessa cosa mentre annullavo un ultimo push per un solo file. Finito per tornare allo stato originale del repository. Stavo usando i comandi git di Linus perché avevo la copia locale su Linux. Fortunatamente quella copia era ancora intatta.

Tutto quello che ho fatto è stato (dopo freneticamente facendo alcuni più copie del repo locale):

git add . 
git status 

(si dice che l'origine/padrone era in vantaggio di 68 commit, bene ... quelli erano tutti i commit Ho cancellato)

git remote set-url origin <GIT_SSH_URL> 
git push 

E tutto è stato ripristinato così com'era prima che facessi una spinta forzata. La cosa più importante da ricordare non è mai fare un checkout git. dopo aver forzatamente spinto. Ma la cosa migliore è disabilitare l'opzione push. Non lo userò mai più. Ho imparato la mia lezione !!

32

Se si conosce l'hash di commit, è facile, basta ricreare il ramo.

5794458...b459f069 master -> master (forced update) 

Eliminare il ramo remoto:

git push origin :master 

quindi ricreare il ramo con i seguenti comandi:

git checkout 5794458 
git branch master 
git push origin master 
+0

GRAZIE !!! Lo adoro –

+0

Esattamente quello che stavo cercando. –

+0

Genio. Questo mi ha salvato un sacco di lavoro – fduembgen

8

La soluzione è già menzionato here

# work on local master 
git checkout master 

# reset to the previous state of origin/master, as recorded by reflog 
git reset --hard origin/[email protected]{1} 

# at this point verify that this is indeed the desired commit. 
# (if necessary, use git reflog to find the right one, and 
# git reset --hard to that one) 

# finally, push the master branch (and only the master branch) to the server 
git push -f origin master 
0

Se non si è in un repo locale da cui è provenuta la spinta forzata, a livello di origine/livello principale non è possibile recuperare.Ma se siete fortunati sufficiente utilizzare GitHub o GitHub for Enterprise, si può avere uno sguardo alla REST API e recuperare perso impegnarsi come patch, ad esempio:

  1. lista degli eventi e trovare la
commettere formato lungo SHA1

https://api.github.com/repos/apache/logging-log4j2/events

  1. Scarica il los t impegnarsi e recuperare la relativa patch nella percorso JSON .files []/patch

https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de

  1. Applicare localmente e spingere di nuovo

git applicare patch.patch & & git commit -m "restaurato commit" & & git push origine master