Como reverto do meu estado atual para uma captura instantânea feita em um determinado commit?
Se eu fizer git log
, então recebo a seguinte saída:
$ 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 reverto para o commit a partir de 3 de novembro, ou seja, commit 0d1d7fc
?
git
git-checkout
git-reset
git-revert
Crazy Serb
fonte
fonte
Respostas:
Isso depende muito do que você quer dizer com "reverter".
Alternar temporariamente para uma confirmação diferente
Se você quiser voltar temporariamente, brincar e voltar para onde está, tudo o que você precisa fazer é verificar o commit desejado:
Ou, se você quiser fazer confirmações enquanto estiver lá, vá em frente e faça uma nova ramificação enquanto estiver nisso:
Para voltar para onde você estava, basta verificar o ramo em que estava novamente. (Se você fez alterações, como sempre ao trocar de ramificação, precisará lidar com elas conforme apropriado. Você pode redefinir para jogá-las fora; você pode esconder, fazer check-out, esconder pop para levá-las com você; pode comprometer para uma filial lá, se você quiser uma filial lá.)
Exclusões definitivas confirmadas não publicadas
Se, por outro lado, você realmente deseja se livrar de tudo o que fez desde então, há duas possibilidades. Primeiro, se você não publicou nenhum desses commits, basta redefinir:
Se você errar, você já descartou as alterações locais, mas pode pelo menos voltar para onde estava antes, redefinindo novamente.
Desfazer confirmações publicadas com novas confirmações
Por outro lado, se você publicou o trabalho, provavelmente não deseja redefinir a ramificação, pois isso está reescrevendo efetivamente o histórico. Nesse caso, você poderia realmente reverter os commits. Com o Git, revert tem um significado muito específico: crie um commit com o patch reverso para cancelá-lo. Dessa forma, você não reescreve nenhum histórico.
A página de
git-revert
manual realmente cobre muito disso em sua descrição. Outro link útil é esta seção do git-scm.com sobre o git-revert .Se você decidir que não deseja reverter, afinal, você pode reverter a reversão (conforme descrito aqui) ou redefinir para antes da reversão (consulte a seção anterior).
Você também pode encontrar esta resposta útil neste caso:
Como mover o HEAD de volta para um local anterior? (Cabeça destacada)
fonte
git revert HEAD~3
como a melhor maneira de reverter os3
commits é uma convenção importante.git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
git revert --no-commit hash1 hash2 ...
e depois disso apenas comprometer cada revert em um commitgit commit -m "Message"
Muitas respostas complicadas e perigosas aqui, mas é realmente fácil:
Isso reverterá tudo, desde o HEAD até o hash de confirmação, o que significa que ele recriará esse estado de confirmação na árvore de trabalho como se todos os commit desde que tivessem voltado. Você pode confirmar a árvore atual e ela criará uma nova confirmação essencialmente equivalente à confirmação para a qual você "reverteu".
(O
--no-commit
sinalizador permite que o git reverta todas as confirmações de uma só vez; caso contrário, você será solicitado a fornecer uma mensagem para cada confirmação no intervalo, desarrumando seu histórico com novas confirmações desnecessárias.)Essa é uma maneira fácil e segura de reverter para um estado anterior . Nenhum histórico é destruído, portanto pode ser usado para confirmações que já foram tornadas públicas.
fonte
--no-edit
vez de--no-commit
, para não precisar editar uma mensagem de confirmação para cada reversão.git diff --cached
.$ git revert --no-commit 53742ae..HEAD
retornafatal: empty commit set passed
81bcc9e HEAD{0}; e475924 HEAD{1}, ...
(a partirgit reflog
), e eu queria desfazer o que eu fiz no81bcc9e
, então eu tinha que fazergit revert e475924..HEAD
Rogue Coder?
Trabalhando por conta própria e só quer que funcione? Siga estas instruções abaixo, elas funcionaram de maneira confiável para mim e para muitas outras por anos.
Trabalhando com outras pessoas? Git é complicado. Leia os comentários abaixo desta resposta antes de fazer algo precipitado.
Revertendo a cópia de trabalho para a confirmação mais recente
Para reverter para uma confirmação anterior, ignorando as alterações:
onde HEAD é o último commit em sua filial atual
Revertendo a cópia de trabalho para uma confirmação mais antiga
Para reverter para uma confirmação mais antiga que a confirmação mais recente:
Os créditos vão para uma pergunta semelhante do Stack Overflow, reverter para um commit por um hash SHA no Git? .
fonte
git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit
.A melhor opção para mim e provavelmente outras é a opção de redefinição do Git:
Esta tem sido a melhor opção para mim! É simples, rápido e eficaz!
Também a partir dos comentários, se você quiser um método menos 'ballzy', poderá usar
fonte
git push -f
bandeira .. Mas tenha cuidado, ele substituirá o controle remoto .. Certifique-se de saber o que deseja fazer ...Antes de responder, vamos adicionar alguns antecedentes, explicando o que
HEAD
é isso .First of all what is HEAD?
HEAD
é simplesmente uma referência ao commit atual (mais recente) no branch atual. Só pode haver um singleHEAD
a qualquer momento (excluindogit worktree
).O conteúdo de
HEAD
é armazenado dentro.git/HEAD
e contém os 40 bytes SHA-1 da confirmação atual.detached HEAD
Se você não está no último commit, o que significa que
HEAD
está apontando para um commit anterior no histórico, é chamadodetached HEAD
.Na linha de comando, será semelhante a este - SHA-1, em vez do nome do ramo, pois ele
HEAD
não está apontando para a ponta do ramo atual:Algumas opções sobre como recuperar de um HEAD desanexado:
git checkout
Isso fará o checkout do novo ramo apontando para o commit desejado. Este comando fará o checkout para um determinado commit.
Nesse ponto, você pode criar uma ramificação e começar a trabalhar a partir deste ponto:
git reflog
Você sempre pode usar o
reflog
também.git reflog
exibirá qualquer alteração que tenha atualizadoHEAD
e o check-out da entrada de reflog desejadaHEAD
retornará a esta confirmação.Sempre que o HEAD for modificado, haverá uma nova entrada no
reflog
Isso o levará de volta ao seu commit desejado
git reset HEAD --hard <commit_id>
"Mova" sua cabeça para o commit desejado.
git rebase --no-autostash
.Este esquema ilustra qual comando faz o quê. Como você pode ver lá,
reset && checkout
modifique o arquivoHEAD
.fonte
git reflog
, isso é exatamente o que eu precisavagit reset HEAD^
--hard`Se você deseja "descomprimir", apagar a última mensagem de confirmação e colocar os arquivos modificados novamente no teste, você usaria o comando:
--soft
indica que os arquivos não confirmados devem ser retidos como arquivos de trabalho, ao contrário dos--hard
que os descartariam.HEAD~1
é o último commit. Se você deseja reverter 3 confirmações, poderá usarHEAD~3
. Se você deseja reverter para um número de revisão específico, também poderá fazer isso usando seu hash SHA.Este é um comando extremamente útil em situações em que você confirmou a coisa errada e deseja desfazer a última confirmação.
Fonte: http://nakkaya.com/2009/09/24/git-delete-last-commit/
fonte
Você pode fazer isso seguindo os dois comandos a seguir:
Isso removerá seu commit anterior do Git.
Se você deseja manter suas alterações, também pode usar:
Em seguida, ele salvará suas alterações.
fonte
Eu tentei várias maneiras de reverter as alterações locais no Git, e parece que isso funciona melhor se você quiser apenas reverter para o estado de confirmação mais recente.
Pequena descrição:
git revert
faz.git checkout <commithashcode>
faz.Encontrei uma maneira muito mais conveniente e simples de obter os resultados acima:
onde HEAD aponta para a confirmação mais recente na filial atual.
É o mesmo código de código sugerido pelo boulder_ruby, mas eu adicionei
git add .
antesgit reset --hard HEAD
para apagar todos os novos arquivos criados desde o último commit, já que é isso que a maioria das pessoas espera que eu acredite ao reverter para o commit mais recente.fonte
OK, voltar para um commit anterior no Git é bastante fácil ...
Reverta sem manter as alterações:
Reverta mantendo as alterações:
Explicação: usando
git reset
, você pode redefinir para um estado específico. É comum usá-lo com um hash de confirmação, como você vê acima.Mas como você vê a diferença é usar os dois sinalizadores
--soft
e--hard
, por padrão,git reset
usar o--soft
sinalizador, mas é uma boa prática sempre usar o sinalizador, explico cada sinalizador:--suave
O sinalizador padrão, conforme explicado, não precisa fornecê-lo, não altera a árvore de trabalho, mas adiciona todos os arquivos alterados prontos para confirmação, para que você volte ao status de confirmação, que muda para os arquivos que ficam sem estágio.
--Difícil
Tenha cuidado com esta bandeira. Ele redefine a árvore de trabalho e todas as alterações nos arquivos rastreados e tudo desaparece!
Também criei a imagem abaixo que pode acontecer na vida real trabalhando com o Git:
fonte
git reset
égit reset --mixed
, nãogit reset --soft
. Por favor, verifique Qual é a diferença entre git reset --mixed, --soft e --hard? e Em inglês simples, o que o “git reset” faz?Supondo que você esteja falando sobre o mestre e sobre o respectivo ramo (dito isso, pode ser qualquer ramo que você esteja preocupado):
Encontrei a resposta em uma postagem de blog (agora não existe mais)
Observe que isso está redefinindo e forçando a alteração no controle remoto, para que, se outros membros de sua equipe já tiverem puxado, você causará problemas para eles. Você está destruindo o histórico de alterações, que é uma razão importante pela qual as pessoas usam o git em primeiro lugar.
Melhor usar reverter (ver outras respostas) do que redefinir. Se você é uma equipe de um homem, provavelmente não importa.
fonte
Digamos que você tenha os seguintes commits em um arquivo de texto chamado
~/commits-to-revert.txt
(eu costumavagit log --pretty=oneline
obtê-los)Crie um script de shell Bash para reverter cada um deles:
Isso reverte tudo de volta ao estado anterior, incluindo criações e exclusões de arquivos e diretórios, e submete-o à sua ramificação e você mantém o histórico, mas você o reverte para a mesma estrutura de arquivo. Por que o Git não tem um
git revert --to <hash>
está além de mim.fonte
git revert HEAD~3
para remover os últimos 3 commits #git revert -n master~3..master~1
? (Como visto em kernel.org/pub/software/scm/git/docs/git-revert.html )git revert --no-commit <start>..<end>
, porquegit revert
aceita um intervalo de confirmação em novas (ou todas?) Versões do Git. Observe que o início do intervalo não está incluído na reversão.Alternativas extras às soluções da Jefromi
As soluções da Jefromi são definitivamente as melhores e você deve usá-las definitivamente. No entanto, por uma questão de integridade, eu também queria mostrar essas outras soluções alternativas que também podem ser usadas para reverter uma confirmação (no sentido em que você cria uma nova confirmação que desfaz alterações na confirmação anterior , exatamente como o
git revert
faz).Para ser claro, essas alternativas não são a melhor maneira de reverter confirmações , são as soluções da Jefromi , mas eu só quero ressaltar que você também pode usar esses outros métodos para obter a mesma coisa que
git revert
.Alternativa 1: redefinições rígidas e flexíveis
Esta é uma versão ligeiramente modificada da solução de Charles Bailey para reverter para um commit por um hash SHA no Git? :
Isso basicamente funciona usando o fato de que as redefinições flexíveis deixarão o estado da consolidação anterior em estágios na área de índice / preparação, que você poderá confirmar.
Alternativa 2: Excluir a árvore atual e substituir pela nova
Esta solução vem da solução svick para o commit antigo do Checkout e o torna um novo commit :
Da mesma forma que a alternativa nº 1, isso reproduz o estado da
<commit>
cópia de trabalho atual. É necessário fazergit rm
primeiro, porquegit checkout
não removerá os arquivos que foram adicionados desde então<commit>
.fonte
git revert HEAD~2..HEAD
com a solução vinculada da @ Cascabel (@ Jefromi). Não estou vendo o problema.Aqui está uma maneira muito mais simples de voltar a um commit anterior (e colocá-lo em um estado não confirmado, para fazer o que você quiser):
Portanto, não há necessidade de confirmar IDs e assim por diante :)
fonte
Existe um comando (que não faz parte do núcleo do Git, mas está no pacote git-extras ) especificamente para reverter e preparar os antigos commit:
Pela página do manual , também pode ser usado como tal:
fonte
A melhor maneira é:
Isso redefinirá a ramificação para o commit específico e fará o upload do servidor remoto com os mesmos commit que você fez no local (isso elimina completamente os comandos após o commit específico)
Tenha cuidado,
--force
pois o sinalizador remove todas as confirmações subsequentes após a confirmação selecionada, sem a opção de recuperá-las.fonte
Após todas as alterações, quando você pressiona todos esses comandos, pode ser necessário usar:
E não somente
git push
.fonte
Você pode concluir todas essas etapas iniciais e retornar ao repositório Git.
Puxe a versão mais recente do seu repositório do Bitbucket usando o
git pull --all
comandoExecute o comando Git log
-n 4
do seu terminal. O número após o-n
determina o número de confirmações no log a partir da confirmação mais recente em seu histórico local.Redefina o cabeçalho do histórico do seu repositório usando
git reset --hard HEAD~N
onde N é o número de confirmações que você deseja recuperar. No exemplo a seguir, o cabeçalho seria atrasado em uma confirmação, até a última confirmação no histórico do repositório:Envie a alteração para o repositório Git usando
git push --force
para forçar a alteração.Se você deseja que o repositório Git tenha um commit anterior:
fonte
Reverta para a confirmação mais recente e ignore todas as alterações locais:
fonte
Selecione o commit necessário e verifique-o
até obter a confirmação necessária. Para fazer o HEAD apontar para isso, faça
ou
git reset --hard HEAD~2
ou o que seja.fonte
git show HEAD
é equivalente a apenas usargit log HEAD -1
.Se a situação for urgente e você quiser fazer o que o interlocutor pediu de maneira rápida e suja , supondo que seu projeto esteja em um diretório chamado, por exemplo, "meu projeto":
RÁPIDO E SUJO : dependendo das circunstâncias, rápido e sujo podem, de fato, ser MUITO BOM. O que minha solução aqui faz NÃO substitui irreversivelmente os arquivos que você possui em seu diretório de trabalho por arquivos arrastados / extraídos das profundezas do repositório git à espreita sob seu diretório .git / usando comandos git incrivelmente inteligentes e diabolicamente poderosos, dos quais existem muitos. VOCÊ NÃO TEM QUE MERGULHAR NO MAR PROFUNDO PARA RECUPERAR o que pode parecer uma situação desastrosa, e tentar fazê-lo sem experiência suficiente pode ser fatal .
Copie o diretório inteiro e chame-o de outra coisa, como "meu projeto - copiar". Supondo que os arquivos do seu repositório git ("repo") estejam no diretório "meu projeto" (o local padrão para eles, em um diretório chamado ".git"), você agora terá copiado os arquivos de trabalho e os arquivos de repo.
Faça isso no diretório "meu projeto":
Isso retornará o estado do repositório em "meu projeto" para o que era quando você fez esse commit (um "commit" significa uma captura instantânea de seus arquivos de trabalho). Todas as confirmações desde então serão perdidas para sempre em "meu projeto", MAS ... elas ainda estarão presentes no repositório em "meu projeto - cópia", uma vez que você copiou todos esses arquivos - incluindo os de ... /. Git /.
Você tem duas versões em seu sistema ... você pode examinar ou copiar ou modificar arquivos de interesse, ou o que for, da confirmação anterior. Você pode descartar completamente os arquivos em "meu projeto - copiar", se tiver decidido o novo trabalho desde que a confirmação restaurada não chegaria a lugar algum ...
O óbvio se você deseja continuar com o estado do projeto sem realmente descartar o trabalho, pois esse commit recuperado é renomear seu diretório novamente: exclua o projeto que contém o commit recuperado (ou atribua um nome temporário) e renomeie seu " meu projeto - copie o diretório "de volta para" meu projeto ". Então talvez tente entender algumas das outras respostas aqui e provavelmente faça outro commit logo.
O Git é uma criação brilhante, mas absolutamente ninguém é capaz de "buscá-lo rapidamente": também pessoas que tentam explicar isso com muita frequência assumem o conhecimento prévio de outros VCS [Version Control Systems] e se aprofundam demais. cedo demais e cometer outros crimes, como usar termos intercambiáveis para "fazer check-out" - de maneiras que às vezes parecem quase calculadas para confundir um iniciante.
Para economizar muito estresse, aprenda com minhas cicatrizes. Você precisa praticamente ler um livro sobre o Git - eu recomendaria "Version Control with Git" . Faça isso mais cedo ou mais tarde. Se o fizer, lembre-se de que grande parte da complexidade do Git vem da ramificação e remessa: você pode pular essas partes em qualquer livro. Da sua pergunta, não há razão para que as pessoas te ceguem com a ciência .
Especialmente se, por exemplo, esta é uma situação desesperadora e você é um novato no Git!
PS: Outro pensamento: agora é bastante simples manter o repositório Git em um diretório diferente daquele com os arquivos de trabalho. Isso significa que você não precisaria copiar todo o repositório Git usando a solução rápida e suja acima. Veja a resposta de Fryer usando
--separate-git-dir
aqui . Entretanto, esteja avisado : se você tiver um repositório de "diretório separado" que não copia e fizer uma reinicialização completa, todas as versões subseqüentes à confirmação de redefinição serão perdidas para sempre, a menos que você tenha, como absolutamente deveria, faça backup regularmente do seu repositório, de preferência para a nuvem (por exemplo, Google Drive ), entre outros lugares.Nesse assunto de "fazer backup na nuvem", o próximo passo é abrir uma conta (é claro) com o GitHub ou (melhor na minha opinião) com o GitLab . Em seguida, você pode
git push
executar regularmente um comando para atualizar seu repositório na nuvem "corretamente". Mas, novamente, falar sobre isso pode ser muito cedo.fonte
Esta é mais uma maneira de redefinir diretamente para uma confirmação recente
Ele limpa diretamente todas as alterações que você está fazendo desde o último commit.
PS: Tem um pequeno problema; ele também exclui todas as alterações de stash armazenadas recentemente. O que eu acho que na maioria dos casos não deve importar.
fonte
Para limpar completamente o diretório de um codificador de algumas alterações acidentais, usamos:
Apenas
git reset --hard HEAD
se livrará de modificações, mas não se livrará de arquivos "novos". No caso deles, eles arrastaram acidentalmente uma pasta importante para algum lugar aleatório, e todos esses arquivos estavam sendo tratados como novos pelo Git, parareset --hard
não corrigi-lo. Ao executar ogit add -A .
antemão, ele rastreou explicitamente todos eles com git, a serem eliminados pela redefinição.fonte
Para manter as alterações do commit anterior no HEAD e passar para o commit anterior, faça:
Se não forem necessárias alterações da confirmação anterior para HEAD e apenas descartar todas as alterações, faça:
fonte
Acredito que algumas pessoas possam chegar a essa pergunta querendo saber como reverter as alterações confirmadas que fizeram em seu mestre - ou seja, jogue tudo fora e volte à origem / mestre, nesse caso, faça o seguinte:
/superuser/273172/how-to-reset-master-to-origin-master
fonte
Reverter é o comando para reverter as confirmações.
Amostra:
git revert 2h3h23233
É capaz de variar desde a CABEÇA como abaixo. Aqui 1 diz "reverter o último commit".
git revert HEAD~1..HEAD
e então faça
git push
fonte
Tente redefinir para o commit desejado -
git reset <COMMIT_ID>
(para verificar COMMIT_ID, use
git log
)Isso redefinirá todos os arquivos alterados para o estado não adicionado.
Agora você pode
checkout
todos os arquivos não adicionados porgit checkout .
Marque
git log
para verificar suas alterações.ATUALIZAR
Se você tem um único compromisso no seu repositório, tente
git update-ref -d HEAD
fonte
Como suas confirmações são enviadas remotamente, você precisa removê-las. Deixe-me supor que seu ramo está se desenvolvendo e é empurrado sobre a origem .
Você primeiro precisa remover o desenvolvimento da origem :
Então você precisa desenvolver o status que deseja, deixe-me assumir que o hash de confirmação é EFGHIJK:
Por fim, pressione desenvolver novamente:
fonte
Eu tive um problema semelhante e queria voltar a um commit anterior. No meu caso, eu não estava interessado em manter o commit mais recente, portanto usei
Hard
.Foi assim que eu fiz:
Isso reverterá no repositório local e, após o uso
git push -f
, atualizará o repositório remoto.fonte
No GitKraken, você pode fazer isso:
Clique com o botão direito do mouse no commit que deseja redefinir e escolha: Redefinir para este commit / Hard :
Clique com o botão direito do mouse no commit novamente, escolha: Nome do ramo atual / Push :
Clique no Force Push :
Obs. : Você precisa ter cuidado, pois todo o histórico de consolidação após a reinicialização forçada é perdido e essa ação é irreversível. Você precisa ter certeza do que está fazendo.
fonte
Se você deseja corrigir algum erro no último commit, uma boa alternativa seria usar o comando git commit --amend . Se o último commit não for apontado por nenhuma referência, isso funcionará, pois ele cria um commit com o mesmo pai que o último commit. Se não houver referência ao último commit, ele será simplesmente descartado e esse commit será o último commit. Essa é uma boa maneira de corrigir confirmações sem revertê-las. No entanto, tem suas próprias limitações.
fonte