Como posso desfazer git redefinir CABEÇA --hard ~ 1?

votos
889

É possível desfazer as alterações causadas pela seguinte comando? Se sim, como?

git reset --hard HEAD~1
Publicado 08/08/2008 em 00:22
fonte usuário
Em outras línguas...                            


13 respostas

votos
1k

Pat Notz está correto. Você pode obter a volta comprometer tanto tempo como tem sido dentro de alguns dias. git única de lixo recolhe após cerca de um mês ou assim, a menos que você diga a ele explicitamente para remover manchas mais recentes.

$ git init
Initialized empty Git repository in .git/

$ echo "testing reset" > file1
$ git add file1
$ git commit -m 'added file1'
Created initial commit 1a75c1d: added file1
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file1

$ echo "added new file" > file2
$ git add file2
$ git commit -m 'added file2'
Created commit f6e5064: added file2
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 file2

$ git reset --hard HEAD^
HEAD is now at 1a75c1d... added file1

$ cat file2
cat: file2: No such file or directory

$ git reflog
1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD
f6e5064... HEAD@{1}: commit: added file2

$ git reset --hard f6e5064
HEAD is now at f6e5064... added file2

$ cat file2
added new file

Você pode ver no exemplo que o file2 foi removido como resultado do hard reset, mas foi colocado de volta no lugar quando eu redefinir através do reflog.

Respondeu 22/08/2008 em 05:36
fonte usuário

votos
308

O que você quer fazer é especificar o SHA1 do commit que você quer restaurar. Você pode obter o sha1 examinando a reflog ( git reflog) e, em seguida, fazendo

git reset --hard <sha1 of desired commit>

Mas não espere muito tempo ... depois de algumas semanas git acabará por ver que cometer como unreferenced e eliminar todas as bolhas.

Respondeu 09/08/2008 em 06:30
fonte usuário

votos
117

A resposta está escondida na resposta detalhada acima, você pode simplesmente fazer:

$> git reset --hard HEAD@{1}

(Veja a saída do show de reflog git )

Respondeu 26/02/2011 em 16:13
fonte usuário

votos
82

É possível recuperá-lo se Git não tem lixo coletado ainda.

Obter uma visão geral do pendurada commits com fsck:

$ git fsck --lost-found
dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf

Recuperar o pendurada comprometer com rebase:

$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
Respondeu 22/08/2008 em 07:11
fonte usuário

votos
32

Se você tiver muita sorte, como eu estava, você pode voltar para o seu editor de texto e clique em 'desfazer'.

Eu sei que não é realmente uma resposta adequada, mas me salvou metade um dia de trabalho por isso espero que ele vai fazer o mesmo para outra pessoa!

Respondeu 13/01/2012 em 01:48
fonte usuário

votos
26

Exemplo de caso IRL:

$ git fsck --lost-found

Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 025cab9725ccc00fbd7202da543f556c146cb119
dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b
dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4
dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98
dangling blob 9183b84bbd292dcc238ca546dab896e073432933
dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee
dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22
dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd
dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7
dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66
dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b
dangling blob b87163c8def315d40721e592f15c2192a33816bb
dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7
dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133
dangling blob 4a71f9ff8262701171d42559a283c751fea6a201
dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2
dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed
dangling blob 749ffc9a412e7584245af5106e78167b9480a27b
dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a    <- it's this one

$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a

commit f6ce1a403399772d4146d306d5763f3f5715cb5a
Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local>
Date:   Wed Aug 15 08:41:30 2012 +0200

    *MY COMMIT MESSAGE IS DISPLAYED HERE*

diff --git a/Some.file b/Some.file
new file mode 100644
index 0000000..15baeba
--- /dev/null
+++ b/Some.file
*THE WHOLE COMMIT IS DISPLAYED HERE*

$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a

First, rewinding head to replay your work on top of it...
Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.
Respondeu 15/08/2012 em 08:01
fonte usuário

votos
25

tanto quanto eu sei, --hardvai descarta as alterações não confirmadas. Uma vez que estes não são rastreados pelo git. mas você pode desfazer a discarded commit.

$ git reflog

listas serão:

b0d059c HEAD@{0}: reset: moving to HEAD~1
4bac331 HEAD@{1}: commit: added level introduction....
....

onde 4bac331representa a discarded commit.

Agora é só mover a cabeça para que cometem ::

$ git reset --hard 4bac331
Respondeu 02/04/2015 em 08:57
fonte usuário

votos
20

Se você ainda não lixo coletado seu repositório (por exemplo, usando git repack -dou git gc, mas note que a coleta de lixo também pode acontecer automaticamente), então o seu comprometer ainda está lá - é apenas não acessível através da cabeça.

Você pode tentar encontrar o seu cometer olhando através da saída git fsck --lost-found.

Versões mais recentes do Git tem algo chamado "reflog", que é um registro de todas as alterações que são feitas para os juízes (em oposição às alterações que são feitas ao conteúdo do repositório). Assim, por exemplo, cada vez que você mudar sua cabeça (ou seja, cada vez que você fazer um git checkoutpara alternar ramos), que será registrado. E, claro, o seu git resettambém manipulou a cabeça, então ele também foi registrado. Você pode acessar estados mais velhos de seus refs em uma maneira similar que você pode acessar estados mais velhos de seu repositório, usando um @sinal, em vez de um ~, como git reset HEAD@{1}.

Levei um tempo para entender qual é a diferença entre a cabeça @ {1} e CABEÇA ~ 1, então aqui está uma pequena explicação:

git init
git commit --allow-empty -mOne
git commit --allow-empty -mTwo
git checkout -b anotherbranch
git commit --allow-empty -mThree
git checkout master # This changes the HEAD, but not the repository contents
git show HEAD~1 # => One
git show HEAD@{1} # => Three
git reflog

Então, HEAD~1significa "ir para o commit antes da submissão que CABEÇA aponta atualmente em", enquanto que HEAD@{1}significa "ir para o commit que a cabeça apontada para antes que apontou para onde ele aponta atualmente em".

Que lhe permitirá facilmente para encontrar seu perdido cometer e recuperá-lo.

Respondeu 27/08/2008 em 04:45
fonte usuário

votos
19

Na maioria dos casos, sim.

Dependendo do estado de seu repositório estava quando você executou o comando, os efeitos da git reset --hardgama lata de ser trivial para desfazer, basicamente impossível.

Abaixo eu listei uma série de diferentes cenários possíveis, e como você pode recuperar a partir deles.

Todas as minhas alterações foram cometidos, mas agora os commits se foram!

Essa situação geralmente ocorre quando você executa git resetcom um argumento, como em git reset --hard HEAD~. Não se preocupe, isso é fácil de recuperar!

Se você apenas correu git resete não têm feito outra coisa desde então, você pode voltar para onde você estava com este one-liner:

git reset --hard @{1}

Isso redefine o ramo atual qualquer estado em que estava antes da última vez que foi modificado (no seu caso, a mais recente modificação para o ramo seria o hard reset que você está tentando desfazer).

Se, no entanto, você fez outras modificações para o seu ramo desde o reset, o one-liner acima não irá funcionar. Em vez disso, você deve executar para ver uma lista de todas as alterações recentes feitas em seu ramo (incluindo resets). Essa lista será algo parecido com isto:git reflog <branchname>

7c169bd master@{0}: reset: moving to HEAD~
3ae5027 master@{1}: commit: Changed file2
7c169bd master@{2}: commit: Some change
5eb37ca master@{3}: commit (initial): Initial commit

Encontre a operação nesta lista que você quer "desfazer". No exemplo acima, seria a primeira linha, aquela que diz "reset: mover-se para CABEÇA ~". Em seguida, copie a representação da comprometer antes (abaixo) essa operação. No nosso caso, isso seria master@{1}(ou 3ae5027, ambos representam o mesmo commit), e correr git reset --hard <commit>para repor a sua filial atual de volta para que cometeu.

I encenado minhas alterações com git add, mas nunca cometeu. Agora as minhas alterações são ido!

Este é um pouco mais complicado para se recuperar. git faz tem cópias dos arquivos que você adicionou, mas desde que essas cópias não estavam vinculados a qualquer particular, comprometer você não pode restaurar as alterações de uma só vez. Em vez disso, você tem que localizar os arquivos individuais na base de dados do git e restaurá-los manualmente. Você pode fazer isso usando git fsck.

Para mais detalhes sobre isso, consulte Undo git redefinir --hard com arquivos não confirmadas na área de preparo .

I teve alterações em arquivos no meu diretório de trabalho que eu nunca encenadas com git add, e nunca cometeram. Agora as minhas alterações são ido!

Uh oh. Eu odeio dizer isso, mas provavelmente você está sem sorte. Git não armazenar as alterações que você não adicionar ou comprometer-se a isso, e de acordo com a documentação paragit reset :

--Difícil

Repõe o índice e árvore de trabalho. Quaisquer alterações em arquivos rastreados na árvore trabalhando desde <commit>são descartados.

É possível que você pode ser capaz de recuperar as suas alterações com algum tipo de utilitário de recuperação de disco ou um serviço de recuperação de dados profissional, mas neste momento isso é provavelmente mais problemas do que vale a pena.

Respondeu 16/01/2015 em 18:37
fonte usuário

votos
10

Eu sei que isto é uma discussão antiga ... mas como muitas pessoas estão procurando maneiras de desfazer o material em Git, eu ainda acho que pode ser uma boa idéia para continuar dando dicas aqui.

Quando você fazer um "git add" ou mover qualquer coisa a partir do canto superior esquerdo para o canto inferior esquerdo no gui git o conteúdo do arquivo é armazenado em um blob e o conteúdo do arquivo é possível recuperar do que blob.

Por isso, é possível recuperar um arquivo, mesmo que não foi cometido, mas tem que foram adicionados.

git init  
echo hello >> test.txt  
git add test.txt  

Agora, o blob é criada, mas é referenciado pelo índice para que ele não vai ser listado com fsck git até que repor. Por isso, redefinir ...

git reset --hard  
git fsck  

você vai ter um ce013625030ba8dba906f756967f9e9ca394464a blob pendurado

git show ce01362  

vai dar-lhe o conteúdo do arquivo "Olá" de volta

Para encontrar commits sem referência eu encontrei uma dica em algum lugar sugerindo isso.

gitk --all $(git log -g --pretty=format:%h)  

Eu tê-lo como uma ferramenta na gui git e é muito útil.

Respondeu 20/01/2014 em 07:27
fonte usuário

votos
2

Fez um pequeno script para torná-lo um pouco mais fácil encontrar a cometer um está procurando:

git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'

Sim, ele pode ser consideravelmente mais bonita com awk ou algo parecido, mas é simples e eu só precisava. Pode salvar alguém de 30 segundos.

Respondeu 11/03/2014 em 09:09
fonte usuário

votos
1

Antes de responder permite adicionar um pouco de fundo, explicando o que é isso HEAD.

First of all what is HEAD?

HEADé simplesmente uma referência para o commit atual (mais recente) no ramo atual.
Só pode haver uma única HEADem um determinado momento. (excluindo git worktree)

O conteúdo de HEADé armazenado no interior .git/HEADe que contém os 40 bytes SHA-1 da corrente de cometer.


detached HEAD

Se você não está na mais recente comprometer - significado que HEADestá apontando para um antes cometer na história o seu chamado detached HEAD.

digite descrição da imagem aqui

Na linha de comando ele vai olhar como this- SHA-1 em vez do nome do ramo desde o HEADnão está apontando para a ponta do ramo atual

digite descrição da imagem aqui


Algumas opções sobre como se recuperar de uma cabeça destacada:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Isto irá fazer o checkout nova que aponta ramo para o desejado cometer.
Este comando irá fazer o checkout a uma determinada cometer.
Neste ponto, você pode criar uma filial e começar a trabalhar a partir deste ponto.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Você sempre pode usar o reflogbem.
git reflogirá exibir qualquer mudança que atualizou a HEADe verificar a entrada reflog desejado irá definir a HEADvolta a esta cometer.

Toda vez que a cabeça é modificado haverá uma nova entrada na reflog

git reflog
git checkout HEAD@{...}

Isto fará você volta para o seu desejado cometer

digite descrição da imagem aqui


git reset HEAD --hard <commit_id>

"Mover" a cabeça de volta para o desejado cometer.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.
  • Nota: ( Desde Git 2.7 )
    você também pode usar o git rebase --no-autostashbem.


git revert <sha-1>

"Undo" o dado cometer ou cometer gama.
O comando de reset vai "desfazer" as alterações feitas no dado cometer.
Um novo comprometer com o patch undo será comprometida enquanto o original cometer permanecerá na história também.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Este esquema ilustrar qual comando faz o quê.
Como você pode ver, existem reset && checkoutmodificar o HEAD.

digite descrição da imagem aqui

Respondeu 21/04/2018 em 16:30
fonte usuário

votos
1

Eu apenas fiz um hard reset no projeto errado. O que salvou minha vida foi a história local do Eclipse. IntelliJ IDEA é dito ter um, também, e assim pode seu editor, vale a pena conferir:

  1. tópico de ajuda Eclipse sobre a história local
  2. http://wiki.eclipse.org/FAQ_Where_is_the_workspace_local_history_stored%3F
Respondeu 07/04/2017 em 08:46
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more