Como cancelar uma confirmação git local

744

Meu problema é que alterei um arquivo, por exemplo: README, adicionei uma nova linha ' this for my test line ' e salvei o arquivo, depois emiti os seguintes comandos

 git status

 # On branch master
 # Changed but not updated:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #  modified:   README
 #
 no changes added to commit (use "git add" and/or "git commit -a")


 git add README

 git commit -a -m 'To add new line to readme'

Não forcei o código no github, agora quero cancelar esse commit.

Para isso eu usei

   git reset --hard HEAD~1

Mas perdi a linha recém-adicionada ' this for my test line ' do arquivo README. Isso não deveria acontecer. Eu preciso que o conteúdo esteja lá. Existe uma maneira de reter o conteúdo e cancelar meu commit local?

Amal Kumar S
fonte
3
Parece que você definitivamente não está pedindo git revert, o que cria um novo commit com o diff inverso do commit revertido. A redefinição simplesmente aponta sua ramificação atual para uma confirmação diferente, nesse caso, a anterior à confirmação que você deseja "esquecer".
Cascabel 31/01
1
NB: Vale a pena mencionar que git-commitpode ser abortado se você deixar a mensagem em branco; portanto, se você ainda não concluiu o commit, isso pode ser útil.
GKFX

Respostas:

1423

Basta usar git resetsem a --hardbandeira:

git reset HEAD~1

PS: Em sistemas baseados em Unix, você pode usar o HEAD^que é igual a HEAD~1. No Windows HEAD^não funcionará porque ^sinaliza uma continuação de linha. Portanto, seu prompt de comando apenas perguntará a você More?.

Koraktor
fonte
13
A propósito, isso é chamado --mixed no manual .
Josh Lee
10
Versões mais recentes do Git até permitem isso @^como uma abreviação para HEAD^.
Koraktor 15/09/14
Eu não sei o que este fez, mas um monte de arquivos appeard na minha lista mudança, arquivos de eu não tocar
FRR
@feresr Se você realmente não tocou nesses arquivos no último commit ou na árvore de trabalho, isso é causado por outras inconsistências na sua árvore de trabalho, por exemplo, você está no Windows e as terminações de arquivos não coincidem.
Koraktor
1
é possível redefinir todos os commit por um lado?
Webwoman
185

Use em --softvez de --hardsinalizar:

git reset --soft HEAD^
TpED
fonte
18
você pode explicar a diferença entre as 2 bandeiras?
John Giotta
1
Se você abrir o Package Manager Console e executar este "git reset --soft HEAD ^", ele fará o que você deseja (e o que eu precisava).
David Cornelson
54
@JohnGiotta - git reset --soft HEAD^irá remover último local (unpushed) cometer, mas vai manter as alterações que você fez
FIDER
@fider Salvador! Não tenho certeza se a resposta aceita ainda funciona, mas essa deve ser a resposta exata que o OP precisava.
Babu
git reset --soft HEAD~no windows
Jack0fshad0ws
34

Se você estiver no meio de um commit (ou seja, já no seu editor), poderá cancelá-lo excluindo todas as linhas acima da primeira #. Isso abortará o commit.

Portanto, você pode excluir todas as linhas para que a mensagem de confirmação fique vazia e salve o arquivo:

Deve ficar assim.

Em seguida, você receber uma mensagem que diz Aborting commit due to empty commit message..

EDITAR :

Você também pode excluir todas as linhas e o resultado será exatamente o mesmo.

Para excluir todas as linhas no vim (se esse for o seu editor padrão), quando estiver no editor, digite ggpara ir para a primeira linha e, em seguida, dGpara excluir todas as linhas. Por fim, escreva e saia do arquivo wqe seu commit será abortado.

inostia
fonte
3
Era exatamente isso que eu estava procurando! Esta resposta precisa de mais upvotes :)
jdunk
FYI, este também funciona se você está tentando abortar umrebase -i mybranchname
inostia
18

A primeira coisa que você deve fazer é determinar se deseja manter as alterações locais antes de excluir a mensagem de confirmação.

Use git logpara mostrar as mensagens de confirmação atuais e encontre o commit_id antes da confirmação que você deseja excluir, não a confirmação que deseja excluir.

Se você deseja manter os arquivos alterados localmente e apenas excluir a mensagem de confirmação:

git reset --soft commit_id

Se você deseja excluir todos os arquivos alterados localmente e a mensagem de confirmação:

git reset --hard commit_id

Essa é a diferença de macio e duro

Mistdon
fonte
1
Eu acho que é o contrário.
precisa saber é o seguinte
9

Você pode dizer ao Git o que fazer com o seu índice (conjunto de arquivos que se tornará o próximo commit) e o diretório de trabalho ao executar a redefinição do git usando um dos parâmetros:

--soft: Somente confirmações serão redefinidas, enquanto o Índice e o diretório de trabalho não são alterados.

--mixed: Isso redefinirá o índice para corresponder ao HEAD, enquanto o diretório de trabalho não será tocado. Todas as alterações permanecerão no diretório de trabalho e aparecerão como modificadas.

--hard: Redefine tudo (confirma, indexa, diretório de trabalho) para corresponder ao HEAD.

No seu caso, eu usaria git reset --softpara manter as alterações modificadas no Índice e no diretório de trabalho. Certifique-se de verificar isso para obter uma explicação mais detalhada.

Nesha Zoric
fonte
1

Use o comando abaixo:

$ git reset HEAD~1

Após isso, você também poderá visualizar os arquivos que retornam como abaixo da resposta.

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
Omkar
fonte