Como reverter um repositório Git para uma persistência anterior

Como é que passo do meu estado actual para um instantâneo feito num determinado commit?

Se eu fizer git log, Então eu recebo o seguinte resultado:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <[email protected]>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <[email protected]>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <[email protected]>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <[email protected]>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

Como reverter para o commit a partir de 3 de novembro, ou seja, commit 0d1d7fc?

Author: Peter Mortensen, 2010-11-06

30 answers

Isto depende muito do que queres dizer com "reverter".

Mudar temporariamente para outro commit

Se você quer voltar temporariamente para ele, brincar, em seguida, voltar para onde você está, tudo que você tem que fazer é verificar o commit desejado:

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32
Ou se você quer fazer commits enquanto estiver lá, faça um novo branch enquanto estiver lá.
git checkout -b old-state 0d1d7fc32
Para voltar para onde estava, verifique o ramo onde estava. (Se você fez mudanças, como sempre quando mudar de ramos, você terá que lidar com eles conforme apropriado. Você poderia reiniciar para jogá-los fora; você poderia esconder, checkout, stash pop para levá-los com você; você poderia enviá-los para um branch lá se você quiser um branch lá.)

Apagar as autorizações não publicadas

Se, por outro lado, queres mesmo livrar-te de tudo o que fizeste desde então, há duas possibilidades. Um, se você não publicou nenhum destes commits, simplesmente reiniciar:
# 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.
Se fizeres asneira, já deitaste fora as tuas mudanças locais, mas podes pelo menos voltar ao que eras antes, reiniciando-as de novo.

Anulação de autorizações publicadas com novas autorizações

Por outro lado, se você publicou o trabalho, você provavelmente não quer reiniciar o ramo, já que isso é efetivamente reescrever a história. Nesse caso, poderias reverter os compromissos. Com o Git, o revert tem um significado muito específico: criar um commit com o patch inverso para cancelar. Assim não reescreves nenhuma história.
# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

A git-revert manpage {[28] } na verdade, cobre muito disso na sua descrição. Outro link útil é Este git-scm.com secção sobre o git-revert.

Se decidir que não queria reverter afinal de contas, poderá reverter a reversão (como descrito aqui) ou reiniciar para antes da reversão (veja a secção anterior).

Também pode achar esta resposta útil neste caso.:
como se mover Voltar para um local anterior? (Cabeça solta)

 8014
Author: Cascabel, 2018-04-04 17:54:07

A reverter a cópia de trabalho para o Commit mais recente

Para reverter para uma persistência anterior, ignorando quaisquer alterações:

git reset --hard HEAD

Onde o HEAD é o último commit no seu ramo actual

Reverter a cópia de trabalho para um Commit mais antigo

Voltar a um commit mais antigo do que o commit mais recente:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Os créditos vão para uma questão semelhante de excesso de pilha, reverter para um commit por um hash SHA em Git?.

 1308
Author: boulder_ruby, 2017-05-23 12:18:27
Muitas respostas complicadas e perigosas aqui, mas na verdade é fácil.
git revert --no-commit 0766c053..HEAD
git commit

Isto irá reverter tudo da cabeça para o hash do commit, o que significa que irá recriar o estado do commit na árvore de trabalho como se Todos os commits desde então tivessem voltado para trás. Você pode então enviar a árvore atual, e ela irá criar um novo commit essencialmente equivalente ao commit para o qual você "reverteu".

(a bandeira --no-commit permite ao git reverter todos os commits de uma vez- caso contrário, você será solicitado para uma mensagem para cada commit no intervalo, enchendo o seu histórico com novos commits desnecessários.)

Esta é uma maneira segura e fácil de voltar para um estado anterior . Nenhum histórico é destruído, então ele pode ser usado para commits que já foram tornados públicos.

 1267
Author: Yarin, 2014-06-28 20:12:34

A melhor opção para mim e provavelmente para outros é a opção git reset:

git reset --hard <commidId> && git clean -f
Esta tem sido a melhor opção para mim! É simples, rápido e eficaz!

Nota : Como mencionado em comentários, não faça isso se você está compartilhando seu ramo com outras pessoas que têm cópias dos antigos commits

Também dos comentários, se quisesse um método menos 'ballzy', poderia usar

git clean -i

 161
Author: Pogrindis, 2015-07-16 15:31:10
Antes de responder, vamos adicionar um pouco de fundo, explicando o que isto é.

First of all what is HEAD?

HEAD é simplesmente uma referência ao commit atual (último) no ramo atual. Só pode haver um HEAD em determinado momento (excluindo git worktree).

O conteúdo de HEAD é armazenado dentro de .git/HEAD, e contém os 40 bytes SHA - 1 do commit actual.


detached HEAD

Se não estiver a tomar o último commit-significando que HEAD está apontando para um commit anterior na história que é chamado detached HEAD.

Enter image description here

Na linha de comandos irá parecer - se com este-SHA-1 em vez do nome do ramo, uma vez que o HEAD não está a apontar para a ponta do ramo actual:

Enter image description here


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


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 vai ... obter a nova ramificação que aponta para a persistência desejada. Este comando irá sair para um determinado commit. Neste ponto você pode criar um ramo e começar a trabalhar a partir deste ponto em:
# 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

Também podes usar o reflog. git reflog irá mostrar qualquer alteração que actualize o HEAD e se verificar o item de reflog desejado, irá voltar a configurar o HEAD para esta persistência.

Cada vez que a cabeça é modificada haverá uma nova entrada na reflog

git reflog
git checkout HEAD@{...}
Isto vai levá-lo de volta ao seu commit desejado.

Enter image description here


git reset HEAD --hard <commit_id>

"Move" a tua cabeça de volta para o commit desejado.

# 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.

Este esquema ilustra que comando faz o quê. Como você pode ver aqui reset && checkout modifique o HEAD.

Enter image description here

 115
Author: CodeWizard, 2018-07-04 19:25:17

Se quiser "descompletar", apagar a última mensagem de commit e colocar os ficheiros modificados de novo no staging, irá usar o comando:

git reset --soft HEAD~1
  • --soft indica que os ficheiros por persistir devem ser conservados como ficheiros de trabalho em vez de --hard que os rejeitariam.
  • HEAD~1 é o último commit. Se quiser reverter 3 commits, pode utilizar HEAD~3. Se você quiser rollback para um número de revisão específico, você também pode fazer isso usando seu SHA condensado.

Este é um comando extremamente útil em situações em que você cometeu a coisa errada e você quer desfazer esse último commit.

Fonte: http://nakkaya.com/2009/09/24/git-delete-last-commit/

 107
Author: Stephen Ostermiller, 2014-03-04 17:25:52

Eu tentei muitas maneiras de reverter as mudanças locais no Git, e parece que isso funciona melhor se você só quiser reverter para o último estado de commit.

git add . && git checkout master -f

Breve descrição:

  • não criará nenhum commits como git revert faz.
  • não vai separar a tua cabeça como git checkout <commithashcode> faz.
  • irá anular todas as suas alterações locais e apagar todos os ficheiros adicionados desde a última persistência no ramo.
  • Só funciona com nomes de ramos. pode reverter apenas para o commit mais recente no ramo desta forma.

Encontrei uma maneira muito mais conveniente e simples de alcançar os resultados acima:

git add . && git reset --hard HEAD

Onde a cabeça aponta para o mais recente envio para a sua secção actual.

É o mesmo código que boulder_ruby sugeriu, mas eu adicionei git add . antes de git reset --hard HEAD para apagar todos os novos arquivos criados desde o último commit, uma vez que isto é o que a maioria das pessoas esperam que eu acredite quando retornar ao commit mais recente.

 99
Author: Roman Minenok, 2014-06-24 20:08:20

Pode fazer isto pelos seguintes dois comandos:

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

Irá remover a sua persistência anterior do Git.

Se quiser manter as suas alterações, também pode utilizar:

git reset --soft [previous Commit SHA id here]

Então ele irá salvar as suas alterações.

 83
Author: kiran boghra, 2016-07-03 06:30:27

Diga que tem os seguintes commits num ficheiro de texto chamado ~/commits-to-revert.txt (eu usei git log --pretty=oneline para os Obter)

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

Crie um script Bash para reverter cada um deles:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

Isto reverte tudo de volta para o estado anterior, incluindo criações de arquivos e diretórios, e supressões, commit it to your branch e você mantém o histórico, mas você tem ele revertido de volta para a mesma estrutura de arquivos. Porque é que o Git não tem um git revert --to <hash> está para além de mim.

 53
Author: Lance Caraccioli, 2014-06-29 00:13:03

Alternativas adicionais às soluções de Jefromi

As soluções de Jefromi são definitivamente as melhores, e você deve definitivamente usá-las. No entanto, por uma questão de completude, eu também quis mostrar essas outras soluções alternativas, que também pode ser usado para reverter um commit (no sentido de que você cria um novo commit que anula as alterações anteriores cometer, assim como o que git revert faz).

Para ser claro, estas alternativas não são os melhores forma de reverter os commits, as soluções de Jefromi são , Mas eu só quero salientar que você também pode usar esses outros métodos para alcançar a mesma coisa que git revert.

Alternativa 1: Resets duros e moles

Esta é uma versão ligeiramente modificada da solução de Charles Bailey para reverter a um commit de um hash SHA em Git?:
# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"
Isso basicamente funciona usando o fato de que as resets suaves irão deixar o estado do commit anterior encenado em o índice/área de estadiamento, que você pode então enviar.

Alternativa 2: apagar a árvore actual e substituir pela nova

Esta solução vem da solução do svick para Checkout antigo commit e torná - lo um novo commit:

git rm -r .
git checkout <commit> .
git commit

Da mesma forma que a alternativa #1, isto reproduz o estado de <commit> na cópia de trabalho actual. É necessário fazer git rm Primeiro porque git checkout não irá remover os ficheiros que foram adicionados desde <commit>.

 50
Author: 2 revsuser456814, 2017-05-23 11:47:32

Aqui está uma maneira muito mais simples de voltar para um commit anterior (e tê - lo em um estado não recomendado, para fazer com ele o que quiser):

git reset HEAD~1

Então, não há necessidade de IDs de commit e assim por diante:)

 48
Author: Paul Walczewski, 2016-07-03 10:56:38

OK, voltar ao commit anterior no git é muito fácil...

Reverter para trás sem manter as alterações:

git reset --hard <commit>

Reverta mantendo as alterações:

git reset --soft <commit>

Explique: usando o git reset, você pode reiniciar para um estado específico, é comum usá-lo com um hash de commit como você vê acima.

Mas como você vê a diferença é usar as duas bandeiras --soft e --hard, por padrão git reset Usando --soft bandeira, mas é uma boa pratique sempre usando a bandeira, eu explico cada bandeira:


--soft

A opção predefinida, tal como foi explicada, não precisa de a indicar, não muda a árvore de trabalho, mas adiciona todos os ficheiros de alterações prontos a persistir, por isso volta ao estado de persistência que muda para os ficheiros que se encontram Desimpedidos.


--hard

Tenha cuidado com esta bandeira, que reinicia a árvore de trabalho e todas as alterações nos ficheiros rastreados e tudo desaparecerá!

Também criei a imagem abaixo isso pode acontecer na vida real trabalhando com o git:

git reset to a commit

 45
Author: Alireza, 2017-08-02 13:41:55

Assumindo que estás a falar do mestre e do respectivo ramo (que disse, Este pode ser qualquer ramo de trabalho com o qual estás preocupado):

# Revert local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Revert remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master
Encontrei a resposta no blog post apagar o repo Git remoto na persistência específica.
 43
Author: markreyes, 2016-07-03 10:58:59
Nada aqui funcionou para mim além desta combinação exacta.
git reset --hard <commit_hash>
git push origin <branch_name> --force

A chave aqui está a forçar o empurrão, sem commits/commit mensagens extra, etc.

 43
Author: serdarsenay, 2018-04-23 01:47:59

Depois de todas as alterações, quando carregar em todos estes comandos, poderá ter de usar:

git push -f ...

E não apenas git push.

 32
Author: sivi, 2013-09-28 19:07:07

Existe um comando (não uma parte do núcleo Git, mas está no Pacote git-extras) especificamente para reverter e encenar commits antigos:

git back

De acordo com o man page , também pode ser usado como tal:

# Remove the latest three commits
git back 3
 31
Author: Shadow Man, 2014-06-28 20:19:45

Seleccione o commit necessário e verifique-o por

git show HEAD
git show HEAD~1
git show HEAD~2 

Até obter o compromisso necessário. Para esclarecer isso, faça

git reset --hard HEAD~1

Ou git reset --hard HEAD~2 ou seja lá o que for.

 24
Author: tonythomas01, 2014-06-28 19:51:32

Reverter para a persistência mais recente e ignorar todas as alterações Locais:

git reset --hard HEAD
 22
Author: Mohammed Irfan Tirupattur, 2018-07-04 19:28:44

Para manter as alterações do commit anterior para HEAD e mover para o commit anterior, faça:

git reset <SHA>

Se não forem necessárias alterações do commit anterior para o HEAD e descartar todas as alterações, faça:

git reset --hard <SHA>
 19
Author: Vishnu Atrai, 2016-07-03 10:21:53
Para limpar completamente o directório de um codificador de algumas alterações acidentais, usámos:
git add -A .
git reset --hard HEAD

Apenas git reset --hard HEAD vai se livrar de modificações, mas não vai se livrar de arquivos "novos". No caso deles, eles acidentalmente arrastaram uma pasta importante em algum lugar Aleatório, e todos esses arquivos estavam sendo tratados como novos pelo Git, então um reset --hard não corrigiu isso. Executando o git add -A . de antemão, ele os rastreou explicitamente com o git, para ser eliminado pelo reset.

 19
Author: Chris Moschini, 2016-07-03 10:55:25

Esta é mais uma maneira de reiniciar directamente para um commit recente

git stash
git stash clear

Limpa directamente todas as mudanças que tem vindo a fazer desde o último commit.

PS: tem um pequeno problema; também apaga todas as alterações de stash que guardou recentemente. O que, na maioria dos casos, não deve importar.

 19
Author: Point Networks, 2016-07-03 10:57:18
Eu acredito que algumas pessoas podem vir a esta questão querendo saber como reverter mudanças cometidas que fizeram em seu mestre-ou seja, jogar tudo fora e voltar para origem / mestre, e nesse caso, fazer isso:
git reset --hard origin/master

Https://superuser.com/questions/273172/how-to-reset-master-to-origin-master

 18
Author: nevster, 2017-03-20 10:18:20

Você pode completar todos estes passos iniciais e empurrar de volta para o git repo.

  1. Puxe a versão mais recente do seu repositório de Bitbucket usando o git pull --all comando.

  2. Execute o comando de Registo git com-n 4 do seu terminal. O número após o -n determina o número de commits no log a partir do commit mais recente no seu histórico local.

    $ git log -n 4

  3. Repor a cabeça do histórico do seu repositório com o git reset --hard HEAD~N onde N é o número de commits você quer levar a cabeça de volta. No exemplo seguinte a cabeça seria ajustado para trás um persistir, até à última persistência no histórico do repositório:

  4. Empurre a mudança para o git repo usando git push --force para forçar o push alteracao.

Se quiser o repositório git para uma persistência anterior

git pull --all
git reset --hard HEAD~1
git push --force
 18
Author: Nanhe Kumar, 2018-07-05 20:56:59

Reverter é o comando para reverter os commits.

git revert <commit1> <commit2> 

Amostra:

git revert 2h3h23233

É capaz de tirar alcance da cabeça como por baixo. Aqui 1 diz " reverter a última persistência."

git revert HEAD~1..HEAD

E depois fazer git push

 15
Author: Sireesh Yarlagadda, 2016-05-27 06:05:57

Se a situação é uma urgente , e você só quer fazer o que o interrogador pediu de uma maneira rápida e suja , assumindo que o seu projecto está sob o directório "o meu projecto":

  1. Copiar o diretório inteiro e chamá-lo de outra coisa, como "meu projeto - cópia"

  2. Faça:

    git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

Depois tem duas versões no seu sistema... você pode examinar ou copiar ou modificar arquivos de interesse, ou o que quer que, a partir do commit anterior. Você pode descartar completamente os arquivos em "my project-copy", se você decidiu que o novo trabalho não ia a lado nenhum...

A coisa óbvia se quiser continuar com o estado do projecto sem De facto descartar o trabalho, dado que este commit obtido é mudar o nome do seu directório de novo: remova o projecto que contém o commit obtido (ou dê - lhe um nome temporário) e renomeie o seu directório "my project-copy" de volta para "my project". Então provavelmente fazer outro commit justo logo.

Git é um brilhante criação, mas você não pode simplesmente "pegar na mosca": também pessoas que tenta explicar demasiadas vezes suponha conhecimento prévio de outros VCS [Sistemas de Controle de Versão] e mergulhar muito muito profundo, muito em breve, e de cometer outros crimes, como o uso de termos intercambiáveis para "conferir" - de forma que, por vezes, aparecem quase calculado para confundir um iniciante.

Para te poupares ao stress, tens de ler um livro sobre o Git. recomenda "controlo de versões com Git" . E se você pode confiar em mim (ou melhor, minhas cicatrizes) quando eu digo "tem que", segue-se que você pode muito bem fazê-lo agora.. Grande parte da complexidade do Git vem de ramificação e, em seguida, remerging. Mas, pela sua pergunta, não há razão para as pessoas o cegarem com a ciência. Especialmente se, por exemplo, esta é uma situação desesperada e você é um novato com Git!

PS: outro pensamento: é (agora) na verdade, muito simples de manter o repositório Git ("repo") em um diretório diferente daquele com os arquivos de trabalho. Isso significaria que você não teria que copiar o repositório Git inteiro usando a solução rápida e suja acima. Veja a resposta por Fryer usando -- separate-git-dir aqui. esteja avisado , no entanto: se tiver um repositório de "directório separado" que não copia, e fizer um reset rígido, todas as versões subsequentes ao commit de reset serão perdidas para sempre, a menos que você ter, como você absolutamente deve, regularmente backup de seu repositório, de preferência para a nuvem (por exemplo, Google Drive) entre outros lugares.

 12
Author: mike rodent, 2017-05-23 11:55:13

Tente reiniciar para o commit desejado -

git reset <COMMIT_ID>

(para verificar a utilização do 'COMMIT_ID'git log)

Isto irá repor todos os ficheiros alterados em estado não adicionado.

Agora você pode checkout todos os arquivos não adicionados por

git checkout .

Verifique git log para verificar as suas alterações.

Actualizar

Se você tem um e apenas commit no seu repo, tente

git update-ref -d HEAD

 11
Author: optimistanoop, 2018-04-17 10:02:40
Como os seus commits são pressionados remotamente, você precisa removê-los. Deixe-me assumir que o seu ramo está desenvolvido e é empurrado sobre a origem.

Primeiro tem de remover o desenvolvimento da origem:

git push origin :develop (note the colon)

Então você precisa se desenvolver para o status que você quer, deixe-me assumir que o hash commit é EFGHIJK:

git reset --hard EFGHIJK

Por último, empurre desenvolva novamente:

git push origin develop
 10
Author: George Ninan, 2017-04-19 07:18:34

Se quiser corrigir algum erro na última persistência, uma boa alternativa seria usar o comando git commit --amend. Se o último commit não for apontado por nenhuma referência, isto fará o truque, pois ele cria um commit com o mesmo pai que o último commit. Se não houver nenhuma referência ao último commit, ele simplesmente será descartado e este commit será o último commit. Esta é uma boa maneira de corrigir commits sem reverter commits. No entanto, tem as suas próprias limitações.

 9
Author: Upul Doluweera, 2015-07-01 11:35:54

Cuidado! Este comando pode causar a perda do histórico de commit, se o utilizador colocar o commit errado erradamente. Tem sempre apoio extra do teu rabo. onde mais, no caso de cometeres erros, é um pouco mais seguro. :)

Tive um problema semelhante e queria voltar ao Commit anterior. No meu caso, eu não estava intetessed para manter o commit mais novo, Portanto eu usei Hard. Foi assim que fiz:
git reset --hard CommitId && git clean -f

Isto irá reverter no local o repositório, aqui depois de usar o git push -f irá actualizar o repositório remoto.

git push -f
 9
Author: maytham-ɯɐɥʇʎɐɯ, 2018-02-02 13:51:57

Primeiro, obter o texto que identifica o commit em alguma data, fazendo:

git rev-list -n 1 --before="2009-07-27 13:37" origin/master

Imprime o identificador de commit, pega no texto (por exemplo, XXXX) e faz:

git checkout XXXX
 8
Author: Luca C., 2018-01-01 16:45:37