Como desfazer os commits locais mais recentes no Git?
eu acidentalmente cometi os ficheiros errados para Git , mas ainda não pus o commit no servidor.
Como posso desfazer aqueles commits do repositório local ?
30 answers
Desfazer uma persistência & refazer
$ git commit -m "Something terribly misguided" # (0: Your Accident)
$ git reset HEAD~ # (1)
[ edit files as necessary ] # (2)
$ git add . # (3)
$ git commit -c ORIG_HEAD # (4)
-
Este comando é responsável pelo desfazer . Irá desfazer a sua última persistência enquanto deixa a sua árvore de trabalho (o estado dos seus ficheiros no disco) intocada. Você vai precisar adicioná-los novamente antes de você pode cometê-los novamente).
- Faz correcções nos ficheiros das árvores de trabalho.
-
git add
Qualquer coisa que queira incluir no seu novo commit. -
Commit the muda, reutilizando a mensagem antiga de commit.
reset
copiei a cabeça antiga para.git/ORIG_HEAD
;commit
com o-c ORIG_HEAD
irá abrir um editor, que contém inicialmente a mensagem de registo do commit antigo e lhe permite editá-la. Se não precisar de editar a mensagem, poderá usar a opção-C
.
Em alternativa, para editar a persistência anterior (ou apenas a sua mensagem de persistência)), commit --amend
irá adicionar alterações no índice actual à persistência anterior.
Para remover (não reverter) um commit que foi empurrado para o servidor, reescrever o histórico com git push origin master --force
é necessário.
Leitura Adicional
Como posso voltar para um local anterior? (Cabeça separada) & desfazer commits
A resposta acima irá mostrar-lhe git reflog
, que pode usar para determinar o SHA - 1 Para O Compromisso ao qual deseja reverter. Uma vez que você tenha este valor, use a sequência de comandos como explicado acima.
HEAD~
é o mesmo que HEAD~1
. O artigo Qual é a cabeça em git? é útil se quiser retirar vários commits.
Opção 1: git reset --hard
Diz que tens isto, onde C é a tua cabeça E (F) é o estado dos teus ficheiros.
(F)
A-B-C
↑
master
Você quer nuke commit C e nunca mais vê-lo e perder todas as alterações nos arquivos localmente modificados . Você faz isso:
git reset --hard HEAD~1
O resultado riz:
(F)
A-B
↑
master
Agora B é a cabeça. Porque você usou --hard
, seus arquivos são reinicializados para o estado deles no commit B.
Opção 2: git reset
Mas suponha que o commit C não foi um desastre, mas apenas um pouco fora. Você deseja desfazer o commit, mas mantenha as suas alterações para um pouco de edição antes de fazer um commit melhor. Começando de novo daqui, com C como sua cabeça:
(F)
A-B-C
↑
master
Você pode fazer isso, deixando de fora o --hard
:
git reset HEAD~1
Neste caso, o resultado riz:
(F)
A-B-C
↑
master
Em ambos os casos, o HEAD é apenas um indicador para o último commit. Quando você faz um git reset HEAD~1
, Você diz ao Git para mover o ponteiro da cabeça para trás um commit. Mas (a menos que você use --hard
) Você deixa seus arquivos como estavam. Então agora mostra as mudanças que você tinha verificado em C. Você não perdeu nada!
Opção 3: git reset --soft
Para o toque mais leve, você pode até desfazer o seu commit, mas deixar os seus ficheiros e o seu índice :
git reset --soft HEAD~1
Isto não só deixa os teus ficheiros em paz, até deixa o teu índiceem paz. Quando você fizer git status
, Você verá que os mesmos arquivos estão no índice como antes. Na verdade, logo após este comando, você poderia fazer git commit
e você estaria refazendo o mesmo commit que você acabou de ter.
Opção 4: fizeste git reset --hard
e precisas de recuperar o Código
Mais uma coisa: suponha que você destrói um commit como no primeiro exemplo, mas então descobrir que você precisava dele afinal? Azar., certo?
Não, ainda há uma maneira de o recuperar. Digitegit reflog
e você verá uma lista de (parcial) commit {[[70]}shas (isto é, hashs) em que você se mudou. Encontre o commit que você destruiu, e faça isso:
git checkout -b someNewBranchName shaYouDestroyed
Agora ressuscitaste esse compromisso. Os Commits não são destruídos em Git por 90 dias, então você geralmente pode voltar e resgatar um que você não queria se livrar.
Existem duas formas de "desfazer" o seu último envio, dependendo se já tornou ou não público o seu envio (empurrado para o seu repositório remoto):
Como desfazer uma commit local
Digamos que me comprometi localmente, mas agora quero remover esse commit.git log
commit 101: bad commit # Latest commit. This would be called 'HEAD'.
commit 100: good commit # Second to last commit. This is the one we want.
Para restaurar tudo de volta ao que era antes do último commit, precisamos reset
para o commit antes HEAD
:
git reset --soft HEAD^ # Use --soft if you want to keep your changes
git reset --hard HEAD^ # Use --hard if you don't care about keeping the changes you made
Agora git log
vai mostrar que o nosso último commit foi remover.
Como desfazer um compromisso público
Se já tornou públicos os seus commits, irá querer criar um novo commit que irá" reverter " as alterações que fez no seu commit anterior (actual).
git revert HEAD
As suas alterações serão revertidas e prontas para o seu commit:
git commit -m 'restoring the file I removed by accident'
git log
commit 102: restoring the file I removed by accident
commit 101: removing a file we don't need
commit 100: adding a file that we need
Para mais informações, confira princípios do Git-desfazer coisas.
Adicionar / Remover ficheiros para obter as coisas da forma que quiser:
git rm classdir
git add sourcedir
Em seguida, alterar o commit:
git commit --amend
O commit anterior, errôneo, será editado para refletir o novo estado do índice-em outras palavras, será como se você nunca tivesse cometido o erro em primeiro lugar.
Note que só deve fazer isto se ainda não tiver empurrado. Se você empurrou, então você terá que fazer uma correção normalmente.git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"
Ou
git reset --hard HEAD~1
Atenção: o comando acima irá remover permanentemente as modificações dos arquivos .java
(e quaisquer outros arquivos) que você queria enviar.
O hard reset
a {[4] } irá definir a sua cópia de trabalho para o estado do envio antes do envio errado.
Para alterar o último commit
Substitua os ficheiros no índice:
git rm --cached *.class
git add *.java
Então, se for um ramo privado, altera o commit:
git commit --amend
Ou, se for um ramo partilhado, faça um novo commit:
git commit -m 'Replace .class files with .java files'
(para alterar um commit anterior, use o impressionante rebase interactiva .)
ProTip™: Adicionar *.class
a gitignore para impedir que isto volte a acontecer.
To reverter uma persistência
Alterar um commit é a solução ideal se você precisar mudar o último commit, mas uma solução mais geral é reset
.
Pode repor o Git em qualquer commit com:
git reset @~N
Em que N
é o número de commits antes de HEAD
, e @~
reinicia para o commit anterior.
git reset @~
git add *.java
git commit -m "Add .java files"
Confira git help reset
, especificamente as secções sobre --soft
--mixed
e --hard
, para uma melhor compreensão de o que isto faz.
Reflog
Se fizeres asneira, podes sempre usar o reflog para encontrar os commits largados:
$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started
Utilizar git revert <commit-id>
.
Para obter o ID de commit, basta usar git log
.
Se você está planejando desfazer um commit local inteiramente, o que quer que você mude você fez no commit, e se você não se preocupar com nada sobre isso, basta fazer o seguinte comando.
git reset --hard HEAD^1
(este comando irá ignorar todo o seu commit e as suas alterações serão completamente perdidas da sua árvore de trabalho local). Se quiser desfazer o seu commit, mas quiser as suas alterações na área de escalonamento (antes do commit, tal como após git add
), então faça o seguinte comando.
git reset --soft HEAD^1
Agora estás comprometido. os ficheiros vêm para a área de preparação. Suponha que se você quiser subir o palco dos arquivos, porque você precisa editar algum conteúdo errado, então faça o seguinte comando
git reset HEAD
Agora os ficheiros foram enviados da área encenada para a área não coberta. Agora os arquivos estão prontos para editar, então o que quer que você mude, você quer ir Editar e adicioná-lo e fazer um novo commit/novo.
Se tiverExtras do Git instalado, poderá executar git undo
para desfazer a última persistência. git undo 3
vai desfazer os últimos três commits.
prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To [email protected]:thecompany/prometheus.git
+ 09a6480...5a74047 master -> master (forced update)
prompt>
Prefiro usar {[[2]} para este trabalho, porque aparece uma lista bonita onde posso escolher os compromissos para me livrar. Pode não ser tão direto como algumas outras respostas aqui, mas parece certo .
Escolha quantos commits você deseja listar, em seguida, invoque assim (para alistar os últimos três)
git rebase -i HEAD~3
Lista de amostras
pick aa28ba7 Sanity check for RtmpSrv port
pick c26c541 RtmpSrv version option
pick 58d6909 Better URL decoding support
Então o Git irá remover os commits para qualquer linha que remover.
Como corrigir a persistência local anterior
Utilize git-gui (ou semelhante) para executar um git commit --amend
. Da GUI você pode adicionar ou remover arquivos individuais do commit. Você também pode modificar a mensagem de commit.
Como desfazer a anterior persistência local
Basta repor a sua ramificação no local anterior (por exemplo, usando gitk
ou git rebase
). Em seguida, volte a alterar as suas alterações a partir de uma cópia gravada. Após a coleta de lixo em seu repositório local, será como o commit indesejado acontecer. Para fazer tudo isso em um único comando, use git reset HEAD~1
.
Aviso: o uso descuidado de git reset
é uma boa maneira de colocar sua cópia de trabalho em um estado confuso. Recomendo que os noviços Git evitem isto se puderem.
Como desfazer uma autorização pública
Faz uma escolha de cereja reversa. ( git-revert ) para desfazer as alterações.
Se ainda não puxou outras alterações para o seu ramo, pode simplesmente fazer...
git revert --no-edit HEAD
Depois, empurre o seu ramo actualizado para o repositório partilhado.
o histórico de commit irá mostrar ambos os commits, separadamente .
Avançado: correcção do ramo privado no repositório público
Isso pode ser perigoso -- certifique-se de que você tem uma cópia local do branch para repush.
nota também: você não quer fazer isso se alguém pode estar trabalhando no branch.
git push --delete (branch_name) ## remove public version of branch
Limpar sua filial localmente, em seguida, repush...
git push origin (branch_name)
no caso normal, você provavelmente não precisa se preocupar com o seu histórico de commit de filial privada ser impecável. Basta carregar numa persistência de seguimento (veja em 'como desfazer uma persistência pública' acima) e, mais tarde, fazer um squash-merge para esconder o histórico.
Se quiser desfazê-lo permanentemente e clonou algum repositório
O ID da persistência pode ser visto por
git log
Depois podes fazer -
git reset --hard <commit_id>
git push origin <branch_name> -f
Se você cometeu lixo mas não empurrou,
git reset --soft HEAD~1
HEAD~1 is a shorthand for the commit before head. Em alternativa, pode referir-se ao SHA-1 do hash se quiser reiniciar. --soft a opção irá apagar o commit, mas irá deixar todos os seus ficheiros alterados "alterações a serem enviadas", como o estado do git o colocaria.
Se você quiser se livrar de quaisquer alterações nos arquivos rastreados na árvore de trabalho desde o commit antes do uso da cabeça "--hard " instead.
Ou
Se já empurraste e alguém puxou, o que é normalmente o meu caso, não podes usar git reset. Você pode, no entanto, fazer um GIT revert,
git revert HEAD
Isto irá criar um novo commit que reverte tudo o que foi introduzido pelo commit acidental.
Em SourceTree (GUI para o GitHub), pode carregar com o botão direito no commit e fazer um 'Commit invertido'. Isto deve desfazer as suas alterações.
No terminal:
Pode, em alternativa, utilizar:
git revert
Ou:
git reset --soft HEAD^ # Use --soft if you want to keep your changes.
git reset --hard HEAD^ # Use --hard if you don't care about keeping your changes.
Um único comando:
git reset --soft 'HEAD^'
Funciona muito bem para desfazer o último commit local!
Reinicie-o com o comando abaixo usando git
:
git reset --soft HEAD~1
Explique: que git reset
faz, é basicamente reset
para algum commit que você gostaria de ir de volta para, em seguida, se você combiná-lo com --soft
chave, ele vai voltar, mas manter as alterações em seu arquivo(s), de modo a obter de volta ao palco que o arquivo foi adicionado HEAD
é o chefe da sucursal e se você combinar com ~1
(neste caso, você também usar HEAD^
), ele vai voltar só um cometa que o que você querer...
Eu crio os passos na imagem abaixo em mais detalhes para você, incluindo todos os passos que podem acontecer em situações reais e cometendo o código:
Como desfazer o último commit Git?
Para restaurar tudo de volta ao que era antes do último commit, precisamos de reiniciar para o commit antes do HEAD.
-
Se não quiser manter as suas alterações que fez:
git reset --hard HEAD^
-
Se quiser manter as suas alterações:
git reset --soft HEAD^
"Reset the working tree to the last commit"
git reset --hard HEAD^
"limpar ficheiros desconhecidos da árvore de trabalho"
git clean
Ver - Git Referência Rápida
Nota: Este comando irá apagar a sua persistência anterior, por isso use com cuidado! É mais seguro.
Use o reflog para encontrar um estado correcto
git reflog
ACTUALIZAR ANTES DE REINICIAR
Seleccione o reflog correcto (f3cb6e2 no meu caso) e tipo
git reset --hard f3cb6e2
Depois disso, a cabeça do repo será reposta para aquele HEADid.
REGISTAR APÓS REINICIAR
Finalmente, o reflog parece-se com a imagem abaixo.
REVISÃO FINAL
Primeira corrida:
git reflog
Ele irá mostrar-lhe todas as acções possíveis que realizou no seu repositório, por exemplo, commit, merge, pull, etc.
Então faz:
git reset --hard ActionIdFromRefLog
Desfazer a última persistência:
git reset --soft HEAD^
ou git reset --soft HEAD~
Aqui --soft
significa reiniciar para a encenação.
HEAD~
ou HEAD^
significa mover-se para cometer antes da cabeça.
Substituir a última persistência na nova persistência:
git commit --amend -m "message"
Irá substituir o último commit pelo novo commit.
De outra maneira:
Verifique a ramificação que deseja reverter, e depois reponha a sua cópia de trabalho local de volta à persistência que deseja ser a última no servidor remoto (tudo o que se seguir irá passar a bye-bye). Para fazer isso, no SourceTree eu clicei à direita no e selecionado "Reset BRANCHNAME to this commit".
Depois navegue para a pasta local do seu repositório e execute este comando:
git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME
Isto irá apagar todos os commits após o actual no seu repositório local mas só por um ramo.
Type git log
and find the last commit hash code and then enter:
git reset <the previous co>
git reset --soft HEAD^
git rm --cached [files you do not need]
git add [files you need]
git commit -c ORIG_HEAD
Verifique os resultados com o gitk ou o git log --stat
Simples, execute isto na sua linha de comando:
git reset --soft HEAD~
Ainda não adiaste o compromisso.
Se o problema foram os ficheiros extra que enviou (e não os quer no repositório), pode removê-los usando git rm
e depois comutar com --amend
git rm <pathToFile>
Você também pode remover pastas inteiras com -r
, ou mesmo combinar com outros comandos Bash
git rm -r <pathToDirectory>
git rm $(find -name '*.class')
Depois de remover os ficheiros, poderá persistir, com -- amend opção
git commit --amend -C HEAD # the -C option is to use the same commit message
Isto irá reescrever a sua persistência local recente a remover os ficheiros extra, por isso, estes ficheiros nunca serão enviados no push e também serão removidos do seu local .Git repository por GC.
Já adiaste o commit.
Você pode aplicar a mesma solução do outro cenário e, em seguida, fazer git push
com a opção -f
, mas não é recomendado uma vez que substitui o histórico remoto com uma mudança divergente (pode alterar o seu repositorio).
Em vez disso, você tem que fazer o commit sem {[[4]} (Lembre-se deste sobre-Emend`: essa opção reescreve o histórico no último commit).
Para uma commit local
git reset --soft HEAD~1
Ou se não se lembrar exactamente em que commit Está, pode usar
git rm --cached <file>
Para um compromisso empurrado
A forma correcta de remover os ficheiros do histórico do repositório é usando git filter-branch
. Isto é,
git filter-branch --index-filter 'git rm --cached <file>' HEAD
Mas recomendo que use este comando com cuidado. Leia mais em Página Manual do git-filter-branch(1) .
Para reiniciar para a revisão anterior, removendo permanentemente todas as alterações por persistir:
git reset --hard HEAD~1
Comando Git para desfazer os últimos commit / commits anteriores:
Atenção: não use --hard se não souber o que está a fazer. -- hard is too dangerous, and it might delete your files.
O comando básico para reverter a persistência no Git é:
$ git reset --hard <COMMIT -ID>
Ou
$ git reset --hard HEAD~<n>
ID de persistência : ID para a persistência
N: é o número dos últimos commits que deseja reverter
Você pode obter o ID de commit como mostrado abaixo:
$ **git log --oneline**
d81d3f1 function to subtract two numbers
be20eb8 function to add two numbers
bedgfgg function to mulitply two numbers
Em que d81d3f1 e be20eb8 são ID do commit.
Agora vamos ver alguns casos.:
suponha que deseja reverter a última persistência 'd81d3f1'. Aqui estão duas opções:
$ git reset --hard d81d3f1
Ou
$ git reset --hard HEAD~1
suponha que deseja reverter a persistência 'be20eb8':
$ git reset --hard be20eb8
Para informações mais detalhadas, poderá consultar e experimentar alguns outros comandos também para reiniciar a cabeça para um estado especificado:
$ git reset --help