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 - --cached
dovrebbe essere --cache
, e ho scoperto che in realtà non creava la .git/lost-found
directory. 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 find
invocazione 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.)