Você deve conseguir recuperar todos os arquivos adicionados ao índice (por exemplo, como na sua situação, com git add .
), embora possa ser um pouco trabalhoso. Para adicionar um arquivo ao índice, git o adiciona ao banco de dados de objetos, o que significa que ele pode ser recuperado desde que a coleta de lixo ainda não tenha acontecido. Há um exemplo de como fazer isso dado na resposta de Jakub Narębski aqui:
No entanto, tentei fazer isso em um repositório de teste e houve alguns problemas - --cached
deveria haver --cache
, e descobri que ele não criou o .git/lost-found
diretório. No entanto, as seguintes etapas funcionaram para mim:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Isso deve gerar todos os objetos no banco de dados de objetos que não podem ser acessados por nenhum ref, no índice ou por meio do reflog. A saída será semelhante a esta:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... e para cada um desses blobs, você pode fazer:
git show 907b308
Para produzir o conteúdo do arquivo.
Muita produção?
Atualização em resposta a sehe 's comentário abaixo:
Se você achar que tem muitos commits e árvores listados na saída daquele comando, você pode querer remover da saída quaisquer objetos que são referenciados de commits não referenciados. (Normalmente você pode voltar a esses commits por meio do reflog de qualquer maneira - estamos apenas interessados em objetos que foram adicionados ao índice, mas nunca podem ser encontrados por meio de um commit.)
Primeiro, salve a saída do comando, com:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
Agora, os nomes de objeto desses commits inacessíveis podem ser encontrados com:
egrep commit all | cut -d ' ' -f 3
Assim, você pode encontrar apenas as árvores e objetos que foram adicionados ao índice, mas não confirmados em nenhum ponto, com:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
Isso reduz enormemente o número de objetos que você terá que considerar.
Atualização: Philip Oakley abaixo sugere outra maneira de reduzir o número de objetos a serem considerados, que é apenas considerar os arquivos modificados mais recentemente em .git/objects
. Você pode encontrá-los com:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(Encontrei essa find
invocação aqui .) O final dessa lista pode ser assim:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
Nesse caso, você pode ver esses objetos com:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(Observe que você deve remover o /
no final do caminho para obter o nome do objeto.)