git recuperar arquivo excluído onde nenhuma confirmação foi feita após a exclusão

812

Eu apaguei alguns arquivos.

Eu não cometi ainda.

Quero redefinir meu espaço de trabalho para recuperar os arquivos.

Eu fiz um git checkout ..

Mas os arquivos excluídos ainda estão ausentes.

E git statusmostra:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    cc.properties
#   deleted:    store/README
#   deleted:    store/cc.properties
#

Por que não git checkout .redefinir o espaço de trabalho para HEAD?

Homan
fonte
16
se você não tivesse realizado as alterações após a exclusão, git checkout .teria funcionado bem.
faizal
10
@faizal e você perderá suas alterações se fizer isso.
Vasiliy Yorkin
1
Basta pressionar Ctrl-J no git gui no item excluído.
ajeh 27/09/17
git checkout - loja cc.properties / README store / cc.properties
Vinod Pasi
Veja esta resposta: quora.com/…
live-love

Respostas:

787

A saída informa o que você precisa fazer. git reset HEAD cc.propertiesetc.

Isso desestabilizará a operação rm. Depois disso, executar um git statusnovo novamente lhe dirá que você precisa fazer um git checkout -- cc.propertiespara recuperar o arquivo.

Atualização: Eu tenho isso no meu arquivo de configuração

$ git config alias.unstage
reset HEAD

que eu costumo usar para desfazer coisas.

Noufal Ibrahim
fonte
5
Como você faz isso para vários arquivos excluídos? Executar o git reset HEAD <<nome do arquivo>> várias vezes seria complicado, alguma maneira eficiente de fazê-lo?
SubSul 10/05
70
git reset HEAD \*e entãogit checkout -- .
Noufal Ibrahim
3
mas eu modifiquei arquivos.
perfil completo de Jiang YD
@RauliRajande É provável que sua situação seja diferente da descrita na pergunta original.
Noufal Ibrahim 15/0218
1
rm -r ./enginesOpa. Agora git reset engines; git checkout engines.
Kris
209

Você organizou a exclusão e precisa fazer:

git checkout HEAD cc.properties store/README store/cc.properties

git checkout . somente faz check-out do índice em que a exclusão já foi preparada.

CB Bailey
fonte
177

Apenas faça git checkout path/to/file-I-want-to-bring-back.txt

seddonym
fonte
8
funciona apenas se os arquivos não foram confirmados e enviados por push.
mahen3d
23
Não funcionou para mim, o git disse que não conhece nenhum arquivo com esse nome, embora o arquivo seja rastreado. Também não cometi, apenas excluí um arquivo usando o menu de contexto do netbeans por engano.
Zelphir Kaltstahl
4
@Zelphir +1error: pathspec 'file.ext' did not match any file(s) known to git.
Ivan Borshchov
@ user3479125 Acho que seu arquivo nunca foi confirmado. O que git statusdiz sobre isso?
Ki92
12
O status do Git mostrou "file.ext" excluído verde git checkout HEAD -- file.extajudou a restaurá-lo.
Ivan Borshchov
144

Para recuperar todas as exclusões não faseadas de uma só vez, automaticamente, sem especificar cada caminho único:

git ls-files -z -d | xargs -0 git checkout --

Para recuperar todas as exclusões em etapas de uma vez, automaticamente, sem especificar cada caminho único:

git status | grep 'deleted:' | awk '{print $2}' | xargs git checkout --
PaoloC
fonte
12
Eu apaguei acidentalmente mais de 500 arquivos e isso funcionou como um deleite, porque também mantinha todas as minhas alterações válidas (a primeira linha é o que eu usei). Obrigado.
Guy Lowe
1
Excluiu acidentalmente todo o conteúdo de um repositório logo após uma compilação bem-sucedida. O primeiro comando salvou meu bacon.
MonaLisaOverdrive
2
Antes que isso funcionasse para mim, eu tive que correr git status --long | grep 'deleted:' | awk '{print $2}' | xargs git reset HEAD --.
Ian Dunn
1
Muito útil, queria manter arquivos não rastreados, mas livrar-se dos excluídos e modificados, apenas alterou -d para -m para lidar com os modificados.
RaisinBranCrunch
5
Observe que isso não funciona se você tiver espaços em seus nomes de arquivo / caminhos. Eu acho que git ls-files -d | sed -e "s/\(.*\)/'\1'/" | xargs git checkout --vai funcionar.
amigos estão dizendo sobre parsley72
79

Como você está fazendo um git checkout ., parece que você está tentando restaurar sua ramificação de volta ao último estado de confirmação.

Você pode conseguir isso com um git reset HEAD --hard

Atenção

Isso pode remover todas as suas últimas modificações e desestabilizar suas modificações, por exemplo, você pode perder o trabalho. Ele pode ser o que quiser, mas confira a documentação para ter certeza.

Paul T
fonte
39
Uau !! Cuidado com isso !!!! Você pode estar certo, mas alguém pode estar confuso e explodir todo o código. Seria legal se você adicionar um aviso maior.
santiagobasulto
3
Isso é exatamente o que eu precisava. Não explode todo o seu código - simplesmente o traz de volta ao seu commit mais recente.
Andrew Hendrie
2
Acabei com centenas de arquivos ausentes em um ponto. Essa é a única maneira prática de corrigir o problema. Obrigado!
Jonathan Benn
66

se você usou

git rm filename

para excluir um arquivo

git checkout path/to/filename

não funciona, então nesse caso

git checkout HEAD^ path/to/filename

Deveria trabalhar

Aurangzeb
fonte
2
Eu gosto desta resposta. Não há dúvida de que você está afetando apenas o arquivo específico que você removeu. 1) caminho do git checkout / para / nome do arquivo 2) git checkout - caminho / para / nome do arquivo
Ed of the Mountain
Excelente. git checkout HEAD^ path/to/filenametrabalhou para mim desde que eu não tinha confirmado o arquivo.
Moses Ndeda
29

Aqui está o comando que me ajudou no meu mac. Tentei algumas das outras soluções, mas elas não funcionaram para mim.

Versão Git no OSX Mavericks

mac-pro:main chris$ git version
git version 1.8.5.2 (Apple Git-48)

Comando

git checkout HEAD -- path/to/file/file.cc
Chris Hinshaw
fonte
19
git checkout HEAD -- client/src/pp_web/index.cljs
Dustin Getz
fonte
18

Use git ls-filespara fazer check-out de arquivos excluídos (-d) ou modificados (-m).

git checkout $(git ls-files -d)

consulte Como posso restaurar apenas os arquivos modificados em um checkout do git?

rickfoosusa
fonte
muito melhor e mais simples do que outras soluções
joshi123
1
Se alguns arquivos tiverem espaço, você poderá fazer git ls-files -d | xargs -I{} git checkout "{}".
Jean Paul
17

Se você deseja restaurar todos os arquivos de uma só vez

Lembre-se de usar o período, porque ele diz ao git para pegar todos os arquivos.

Este comando redefinirá a cabeça e desestabilizará todas as alterações:

$ git reset HEAD . 

Em seguida, execute isso para restaurar todos os arquivos:

$ git checkout .

Então, fazendo um status git, você obterá:

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Casper Wilkes
fonte
Essa é a solução mais simples e funciona para vários arquivos (digamos que você excluiu vários arquivos / pastas). bom trabalho cara +
Gkiokan 14/09/17
9

Você pode querer ver isso

isso vale para casos em que você usou

git checkout -- .

antes de cometer alguma coisa.

Você também pode se livrar dos arquivos criados que ainda não foram criados. E você não os quer. Com:

git reset -- .
Paulo Linhares - Packapps
fonte
Você não denunciou completamente a resposta que copiou. Na verdade git checkout -- .não ajuda a recuperar arquivos apagados e é equivalente ao que o consulente tentou: git checkout .. A parte que pode trabalhar é aquele que você não copiar: git checkout <file_path>.
Jean Paul
6

Encontrei esta postagem enquanto procurava respostas sobre como cancelar a exclusão de um arquivo que foi excluído no meu diretório de trabalho após uma mesclagem da ramificação de outra pessoa. Nenhuma confirmação ainda foi feita após a mesclagem. Como era uma mesclagem em andamento, não era possível adicioná-lo novamente usando:

$ git reset <commitid#-where-file.cpp-existed> file.cpp

Eu tive que fazer outra etapa além da redefinição para trazer o arquivo de volta:

$ git checkout -- file.cpp
user2453404
fonte
4

Se você não confirmou nenhuma alteração, tudo o que você precisa fazer é ocultar essas alterações e você voltará ao último commit em funcionamento.

git stash
git stash clear
git clean 
Rick
fonte
Colocá-lo na pilha de stash não é uma solução. É um truque.
Robert Dolca
2
Thisc é uma boa solução porque você pode removê-lo do esconderijo. Se é um hack ou não, é uma questão de gosto. Toda a idéia de esconderijo é um truque inteligente.
Eino Mäkitalo
@ EinoMäkitalo feliz que poderia ser de ajuda para você :)
Rick
Eu gosto desta abordagem melhor de todos os listados
ckapilla
3

se você estiver procurando por um diretório excluído.

 git checkout ./pathToDir/*
PPB
fonte
3

Aqui estão casos diferentes como referência para ajudar outras pessoas:

Se a exclusão não tiver sido confirmada , o comando abaixo restaurará o arquivo excluído na árvore de trabalho.

$ git checkout -- <file>

Você pode obter uma lista de todos os arquivos excluídos na árvore de trabalho usando o comando abaixo.

$ git ls-files --deleted

Se a exclusão foi confirmada , localize a confirmação onde ocorreu e recupere o arquivo dessa confirmação.

#find the commit hash where it had this file deleted
$ git rev-list -n 1 HEAD -- <file>

Deve dar algo como c46e81aa403ecb8a0f7a323a358068345, agora use commit # here

$ git checkout <commit>^ -- <file>

Algo parecido com isto: $ git checkout c46e81aa403ecb8a0f7a323a358068345 -

Caso esteja procurando o caminho do arquivo para recuperar, o comando a seguir exibirá um resumo de todos os arquivos excluídos.

$ git log --diff-filter=D --summary

Se você deseja apenas exibir a lista de arquivos:

git log --diff-filter=D --summary | grep "delete mode"
Muhammad Soliman
fonte
2

Para mim o que funcionou foi git checkout {SHA1 of commit with version to restore} "{path to file to restore}"

Por exemplo git checkout 5a6b3179e58edff9c90326b9a04284b02fd67bd0 "src-ui/views/includes/radar.pug"

(executado no ramo em que queremos que o arquivo seja inserido)

Após a execução desse comando, o arquivo restaurado existirá no local original (que precisará ser confirmado)

Dinis Cruz
fonte
e / ou simplesmente um git checkout master path/to/the/file.binpara que você apenas cancele a exclusão desse arquivo sem perder nenhuma outra alteração que possa ter feito. PS: esta deve ser a resposta aceita ...
Edoardo
1

Se você instalou o ToroiseGIT, basta selecionar o item de menu "Reverter ..." para o menu pop-up da pasta pai.

Vasyl Shyrochuk
fonte
1

1. Encontre o commit específico ao qual você deseja reverter usando:

   git log
This command will give you a list of commits done by you .

2.Reveja a essa confirmação usando:

    git revert <commit id> 

Agora sua filial local teria todos os arquivos em particular

Ashutosh S
fonte
Isso funciona se você já confirmou suas alterações.
live-love
1

CUIDADO: comprometa qualquer trabalho que você deseja reter primeiro.

Você pode redefinir sua área de trabalho (e recuperar os arquivos excluídos)

git checkout ./*
Henrique Florêncio
fonte
2
FYI ... este comando apagado todos os meus arquivos de trabalho e não se recuperou a file..beware excluídos
hendr1x
É por isso que você usa este comando para redefinir sua área de trabalho. Eu pensei que seria auto-explicativo.
Henrique Florêncio
1
Esse comando não funciona porque se o arquivo for excluído, ele não será capturado ./*.
Jean Paul
@ JeanPaul talvez eu esteja entendendo mal, mas ele colocou meu espaço de trabalho no estado original (arquivo excluído agora presente).
Marc
@ Marc Poderia funcionar, mas apenas se não houver um arquivo visível no diretório, porque caso contrário ./*será expandido pelo bash para corresponder a esses arquivos antes de ser enviado ao git.
Jean Paul
0

Eu tive o mesmo problema, no entanto, nenhuma das soluções acima funcionou para mim. O que acabei fazendo foi:
- criar um arquivo vazio com o mesmo nome
- comparar este arquivo com o histórico local
- copiar o histórico para o arquivo vazio.

theEUG
fonte
-1

Eu tive o mesmo problema e nenhuma das respostas aqui que tentei funcionou para mim também. Estou usando o Intellij e fiz check-out de uma nova ramificação git checkout -b minimalExamplepara criar um "exemplo mínimo" na nova ramificação de algum problema, excluindo um monte de arquivos e modificando outros no projeto. Infelizmente, embora eu não tenha confirmado nenhuma das alterações no novo ramo "exemplo mínimo", quando fiz check-out do meu ramo "original" novamente todas as alterações e exclusões do ramo "exemplo mínimo" ocorreram no campo " ramo original "também (ou pelo menos apareceu). De acordo comgit status os arquivos excluídos foram apenas de ambos os ramos.

Felizmente, apesar de a Intellij ter me avisado "a exclusão desses arquivos pode não ser totalmente recuperável", consegui restaurá-los (no ramo de exemplo mínimo do qual eles realmente foram excluídos) clicando com o botão direito do mouse no projeto e selecionando Histórico local > Mostrar histórico (e depois Restaurar no item de histórico mais recente que eu queria). Depois que o Intellij restaurou os arquivos no ramo "exemplo mínimo", forcei o ramo para a origem. Depois, voltei para minha ramificação local "original" e corri git pull origin minimalExamplepara recuperá-la também.

geneSummons
fonte