2012-07-23 12 views
9

Normalmente, si può fare:Tutti in scena, ma non impegnati, i file cancellati dopo il rilascio: git resettare TESTA --hard

$ echo "Stanley, you must beware of the Drive bee" > file-a 
$ echo "What's a Drive bee?" > file-b 
$ git init . 
$ git add file-b 
$ git commit file-b -m "We don't know, but whatever error you make with it could be fatal." 
$ git reset --hard HEAD 
$ ls 
file-a file-b 

Credo di aver fatto qualcosa di veramente brutto:

$ echo "What are you doing, you darn ?" > file-a 
$ echo "Can't you see I'm trying to drive?" > file- 
$ git init . 
$ git add -A 
$ git commit file- -m "Oh, my God! [It's] the Drive !" 
$ git reset --hard HEAD 
$ ls 
file- 

Risultato: tutto in scena, ma non impegnati, i file eliminati 0_o

git reset --hard HEAD\^ 
fatal: ambiguous argument 'HEAD^': unknown revision or path not in the working tree. 

c'è qualcosa che posso fare per recuperare il file che ho appena cancellato? In altre parole, è possibile ripristinare un repository git alla condizione in cui era prima (o quando) è stato emesso il comando git add -A?

risposta

20

Sì, sei davvero fortunato. Quello che hai aggiunto all'indice di Git è lì, in qualche modo. Infatti, Git crea oggetti blob per ogni file già quando viene aggiunto all'indice. L'indice stesso memorizza solo gli oggetti dell'albero.

Quindi sì, c'erano oggetti blob creati per i file di staging. Tutto quello che perdi sono le informazioni sull'albero, cioè il percorso e il nome del file, ma puoi recuperare il contenuto.

provare a eseguire git fsck e si dovrebbe ottenere un elenco di blob penzoloni:

Checking object directories: 100% (256/256), done. 
dangling blob ac28af8d84fc71eb247ccf665c6d0f4bf1822520 
dangling blob 2d152ff9f09cb08ebc495f453da63eddaa9e249f 
dangling blob cd9567427762cd8066b4e802e5c170a31a026100 

È quindi possibile recuperare il contenuto facendo git cat-file -p ac28af8d. Ad esempio, è possibile collegarlo a un file:

git cat-file -p ac28af8d > recovered-file 

Fallo per tutti e restituiscili.

+2

Solo una nota per lo più irrilevante che è possibile utilizzare 'git show' come alternativa a' git cat-file -p'. Bella risposta. Non me ne sono reso conto da solo. –

+0

@MichaelMior Vero, di solito uso 'cat-file -p' anche se mi dà lo stesso risultato per qualsiasi tipo di oggetto;) – poke

+0

Grazie! Neanch'io lo sapevo. La realtà un po 'triste è che sarà più facile ricreare tutti i file poiché si trattava di un progetto Android relativamente nuovo e molti file sono stati eliminati, il che significa che un albero relativamente grande è stato perso. Ma dovrei essere in grado di ottenere il codice che ho scritto dai BLOB usando la tua soluzione e aggiungerlo di nuovo. (= – dcow

2

Lo script che segue ripristinare tutti i blob penzolanti dal git fsck uscita in file:

i=0; for x in `git fsck | grep "dangling blob [0-9a-f]" | cut -d ' ' -f 3`; do git cat-file -p $x > /tmp/test${i}; i=$((i+1)) ; done 

Come si può vedere, l'uscita di ciascun file originale viene ripristinato nel generico nome di file/tmp/test $ {i} .. . non ho trovato un modo per ripristinare il nome del file ancora ... il comando che ho provato è git ls-tree:

primo che ho preso oggetti possibili:

./.git/objects/37 
./.git/objects/37/5187f5882593f7e52c8efef602d98f1f049c5d 
./.git/objects/37/98be05fcbd7c79e08703aead800529b362332b 

Quindi, ho provato a eseguire il trucco ls-tree, ma non è riuscito a identificarlo come oggetto valido.

/<myproj>/.git/objects/37 ]$ git ls-tree 5187f5882593f7e52c8efef602d98f1f049c5d 
fatal: Not a valid object name 5187f5882593f7e52c8efef602d98f1f049c5d 
0

Mi piace molto la seguente soluzione da questo answer ad un correlato domanda Stack Overflow:

  1. Usa git log --diff-filter=D --summary per ottenere tutti i commit che sono cancellati i file e le file eliminati
  2. Usa git checkout $commit~1 filename a ripristinare il file eliminato.

È conciso e intuitivo.

+0

Si prega di non pubblicare link solo le risposte ad altre domande di overflow dello stack. Invece, vota/contrassegna per chiudere come duplicato oppure, se la domanda non è un duplicato, * adatta la risposta a questa domanda specifica. * – Rizier123

+0

@ red-goblin il commit è stato brindato. Non puoi effettuare il checkout da un indice che non esiste S = (cioè questo non è un duplicato della domanda che hai collegato, e quindi le sue risposte non si applicano correttamente qui, grazie però) – dcow

Problemi correlati