Dovresti essere in grado di recuperare tutti i file che hai aggiunto all'indice (ad esempio, come nella tua situazione, con git add .) anche se potrebbe essere un po 'di lavoro. Per aggiungere un file all'indice, git lo aggiunge al database degli oggetti, il che significa che può essere ripristinato a condizione che la raccolta dei rifiuti non sia ancora avvenuta. C'è un esempio di come farlo nella risposta di Jakub Narębski qui:
Tuttavia, l'ho provato su un repository di prova, e c'erano un paio di problemi - --cacheddovrebbe essere --cache, e ho scoperto che in realtà non creava la .git/lost-founddirectory. Tuttavia, i seguenti passaggi hanno funzionato per me:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Questo dovrebbe produrre tutti gli oggetti nel database degli oggetti che non sono raggiungibili da alcun riferimento, nell'indice o tramite il reflog. L'output sarà simile a questo:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... e per ciascuno di quei blob, puoi fare:
git show 907b308
Per visualizzare il contenuto del file.
Troppa potenza?
Aggiornamento in risposta a sehe 's commento qui sotto:
Se si scopre di avere molti commit e alberi elencati nell'output di quel comando, è possibile rimuovere dall'output qualsiasi oggetto a cui si fa riferimento da commit non referenziati. (In genere puoi comunque tornare a questi commit tramite il reflog: siamo interessati solo agli oggetti che sono stati aggiunti all'indice ma che non possono essere trovati tramite un commit.)
Per prima cosa, salva l'output del comando, con:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
Ora i nomi degli oggetti di quei commit irraggiungibili possono essere trovati con:
egrep commit all | cut -d ' ' -f 3
Quindi puoi trovare solo gli alberi e gli oggetti che sono stati aggiunti all'indice, ma non sottoposti a commit in qualsiasi momento, con:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
Ciò riduce enormemente il numero di oggetti che dovrai considerare.
Aggiornamento: Philip Oakley di seguito suggerisce un altro modo per ridurre il numero di oggetti da considerare, ovvero considerare solo i file modificati più di recente in .git/objects. Puoi trovarli con:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(Ho scoperto che findinvocazione qui .) La fine di quella lista potrebbe essere simile:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
In tal caso puoi vedere quegli oggetti con:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(Nota che devi rimuovere /alla fine del percorso per ottenere il nome dell'oggetto.)