Desfazer um commit específico no Git que foi enviado para repositórios remotos


789

Qual é a maneira mais simples de desfazer um commit específico que é:

  • não na cabeça ou na CABEÇA
  • Foi enviado para o controle remoto.

Porque se não for o último commit,

git reset HEAD

não funciona E porque foi enviado para um controle remoto,

git rebase -i

e

git rebase --onto

causará algum problema nos controles remotos.

Mais ainda, não quero modificar a história de verdade. Se havia um código incorreto, ele estava presente na história e pode ser visto. Eu só quero isso na cópia de trabalho e não me importo com um commit de mesclagem reversa.

Em outras palavras, qual é o equivalente do Git dos seguintes comandos svn:

svn merge -r 303:295 http://svn.example.com/repos/calc/trunk

que remove todas as alterações de 295 para 302, mesclando inversamente todas as alterações nessas revisões, como um novo commit.

svn merge -c -302 ^/trunk

que desfaz a confirmação 302, é claro, adicionando outra confirmação que mescla inversamente as alterações dessa respectiva confirmação.

Eu pensei que deveria ser uma operação bastante simples no Git e um caso de uso bastante comum. Qual é o sentido dos commits atômicos?

Temos encenar stashing e tudo para garantir os commits são perfeitamente atômica, você não deveria ser capaz de desfazer um ou mais desses commits atômicas facilmente?

Respostas:


1211

Identifique o hash da confirmação, usando git loge use git revert <commit>para criar uma nova confirmação que remove essas alterações. De certa forma, git reverté o inverso de git cherry-pick- o último aplica o patch a um ramo que está faltando, o primeiro o remove de um ramo que o possui.


237
E usar a opção -n, se você quer a parte de trás do código, mas não comprometidos automaticamente novamente
jaygooby

17
O que a opção "m" faz? Tentei o git revert 8213f7d, mas obtive o seguinte: error: Commit 8213f7dad1ed546b434a0d8a64cb783b530a5a30 é uma mesclagem, mas nenhuma opção -m foi fornecida. fatal: revert falhou
Malcolm

10
Para reverter uma mesclagem: git revert -m 1 <hash>
brunozrk

31
Um aviso para quem quiser reverter uma mesclagem: o git revert desfará todas as alterações de dados (ou seja, as alterações no arquivo serão revertidas), mas a mesclagem ainda permanece no histórico. Por esse motivo, se você tentar mesclar a mesma ramificação novamente mais tarde, ela não incluirá nenhuma confirmação da ramificação mesclada antes da mesclagem revertida. Isso provavelmente não é o que você deseja. Para mesclar totalmente a ramificação novamente, você precisará primeiro reverter a confirmação onde você reverteu a mesclagem original. Saiba mais aqui: kernel.mirrors.pair.com/pub/software/scm/git/docs/howto/…
etreworgy

3
O link no comentário por @etreworgy é 404. Eu suspeito que esta é uma versão atualizada do link: kernel.org/pub/software/scm/git/docs/howto/...
Tim Smith

368

Eu não gosto do auto-commit que git revertfaz, então isso pode ser útil para alguns.

Se você quiser apenas os arquivos modificados e não a confirmação automática , poderá usar--no-commit

% git revert --no-commit <commit hash>

que é igual ao -n

% git revert -n <commit hash>

9
Você também pode fazer git reset HEAD~1 --softse você já reverteu sem-n
Daniel

1
Mas git reset HEAD~nnão resolverá desfazer nenhum commit que não possa ser acessado continuamente da cabeça. A consulta é para reverter qualquer confirmação específica.
Sangeethkumarp

Usei essa solução, mas encontrei um conflito no meio da reversão. Depois de resolver o conflito, fiz git revert --continueo que me instruiu. Funcionou, mas infelizmente comprometeu os resultados. Talvez eu precisasse fazer git revert --no-commit --continue.
mareoraft

1
@sangeethkumarp o comentário de Daniel é uma etapa adicional que você pode seguir após o git revert, se você esqueceu o -n; porque nesse ponto a última confirmação é a reversão, portanto, a reinicialização suave desfaz essa confirmação, mas não as alterações de código associadas da reversão
Oliver

@Daniel forneceu soluções pelo comentário trabalhar para mim Muito obrigado '' git reset HEAD ~ 1 --soft ''
Md. Abu Sayed

41

Como ele já foi enviado, você não deve manipular diretamente a história. git revertreverterá alterações específicas de uma confirmação usando uma nova confirmação, para não manipular o histórico da confirmação.


1

Se o commit que você deseja reverter for um commit mesclado (já foi mesclado), você deve escolher uma opção -m 1ou -m 2como mostrado abaixo. Isso permitirá ao git saber qual commit pai do commit mesclado usar. Mais detalhes podem ser encontrados AQUI .

  • git revert <commit> -m 1
  • git revert <commit> -m 2
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.