Como restaurar um diretório inteiro do histórico do repositório git?

90

Eu gostaria de restaurar um diretório inteiro (recursivamente) do histórico do meu repositório git.

Existe apenas 1 ramo (mestre).

Eu sei o commit onde os erros foram incluídos.

Posso usar o hash sha1 do commit pai para restaurar o estado do diretório como estava antes de os erros serem incluídos?

Eu pensei sobre algo assim:

git checkout 348ce0aa02d3738e55ac9085080028b548e3d8d3 path/to/the/folder/

mas não funcionou.

mais procurados
fonte
7
tente adicionar '-' entre as revisões e os caminhos:git checkout 348ce0aa02d3738e55ac9085080028b548e3d8d3 -- path/to/the/folder/
Carlos Campderrós
isso ajudou. Muito obrigado.
desejada em
1
@CarlosCampderrós Escreva isso como uma resposta real e
acumule
@MagnusSkog Eu não tinha certeza se funcionaria, então fiz um comentário apenas para verificar. Agora que tenho certeza de que funciona,
anotei
2
Como uma dica geral, "não funcionou" não é muito útil. Diga-nos por que não funcionou, de preferência com a saída de erro (cortada se for muito longa).
me_e

Respostas:

154

tente adicionar '-' entre revisões e caminhos:

git checkout 348ce0aa02d3738e55ac9085080028b548e3d8d3 -- path/to/the/folder/ 

E se você quiser recuperar um diretório do commit anterior, você pode substituir o hash do commit por HEAD ~ 1, por exemplo:

git checkout HEAD~1 -- path/to/the/folder/ 
Carlos Campderrós
fonte
mesmo comando, propósito quase diferente: stackoverflow.com/questions/953481/…
cregox
18
Porém, há um problema: o OP não especifica se o diretório ainda existe. Para restaurar um diretório existente ao estado de confirmação, o conteúdo do diretório deve ser excluído primeiro. Em outro caso, os arquivos existentes que não existiam no commit antigo não serão removidos.
Alberto
7
+1 @Alberto concorda definitivamente. Fiz rm -Rf path/to/the/folderentão um git checkout 348ce0aa02d3738e55ac9085080028b548e3d8d3 -- path/to/the/folder/- Resultado: aquele caminho tinha exatamente os mesmos arquivos daquele commit, sem diferenças e sem arquivos extras que foram criados após este commit. É isso que eu quero.
therobyouknow de
2
o que ele --faz?
Ray Foss,
2
@RayFoss diz ao git que os seguintes parâmetros são arquivos (caso contrário, eles poderiam ser confundidos com um hash de commit, branch ou qualquer outra coisa). Normalmente não são necessários, mas não
custa
2

Existem duas maneiras fáceis de fazer isso:

Se o commit que incluiu os erros incluiu apenas os erros, use git revertpara inverter os efeitos dele.

Caso contrário, o caminho fácil é este:

  1. git checkout 348…
  2. cp -a path/to/the/folder ../tmp-restore-folder
  3. git checkout HEAD # or whatever
  4. rm -rf path/to/the/folder
  5. mv ../tmp-restore-folder path/to/the/folder
  6. git add path/to/the/folder
  7. git commit -m "revert …"
Daniel Pittman
fonte
1

Se você simplesmente fizer git checkout <SHA-ID>isso, ele o moverá temporariamente para aquele sha-commit.

Cada objeto de commit contém toda a estrutura do disco naquele momento, então se você tiver arquivos lá e precisar copiá-los, você pode fazer isso. Porém, advertindo, você não estará em nenhum branch, então você terá que voltar para o master antes de copiar o arquivo em sua árvore de trabalho e submetê-lo.

Mark Fisher
fonte
Você quer dizer "voltar para o mestre", mestre do checkout?
Pacerier