Por que o git revert se queixa de uma opção -m ausente?

185

Então, eu estou trabalhando em um projeto com outras pessoas, e há vários garfos no github sendo trabalhados. Alguém acabou de corrigir um problema e eu me fundi com o garfo dele, mas então percebi que poderia encontrar uma solução melhor. Quero reverter o commit que acabei de fazer. Eu tentei fazer isso com git revert HEADmas me deu este erro:

fatal: Confirmar <SHA1> é uma mesclagem, mas nenhuma opção -m foi fornecida.

O que isso significa? Quando mesclei e confirmei, usei a opção -m para dizer "Mesclado com <nome do usuário>".

O que eu estou fazendo errado aqui?

icnhzabot
fonte

Respostas:

217

Por padrão, git revertse recusa a reverter uma consolidação de mesclagem, pois o que isso realmente significa é ambíguo. Presumo que você HEADseja de fato um commit de mesclagem.

Se você deseja reverter a consolidação de mesclagem, precisa especificar qual pai da mesclagem deseja considerar o tronco principal, ou seja, para o qual deseja reverter.

Freqüentemente, esse será o pai número um, por exemplo, se você esteve mastere fez git merge unwantede decidiu reverter a mesclagem de unwanted. O primeiro pai seria o seu masterramo de pré-mesclagem e o segundo pai seria a dica de unwanted.

Nesse caso, você pode fazer:

git revert -m 1 HEAD
CB Bailey
fonte
4
OK obrigado. Achei mais fácil alterar os dois arquivos que foram afetados pela mesclagem e depois confirmar algumas das minhas outras alterações também.
Icnhzabot
43
Onde posso encontrar informações se tenho que usar -m1 ou -m2, ...?
Patrick Cornelissen
34
git cat-file -p [MERGE_COMMIT_ID]mostrará as ramificações principais em ordem. O primeiro listado seria -m 1o segundo -m 2.
Nostromo 12/10
2
git revert [HASH] -m 2está me dizendo No ramo 1.x-1.x nada para confirmar, o diretório de trabalho está limpo, mas meu commit não é revertido.
jenlampton
3
Portanto, se eu precisar reverter as 10 mesclagens anteriores (o que é bastante provável, já que o git realiza uma mesclagem automaticamente toda vez que extrao alterações de outro desenvolvedor), tenho que fazer isso para cada mesclagem? É por isso que os fãs do git gostam tanto de rebasear, porque a reversão é basicamente inútil?
Neutrino
46

Digamos que o outro cara tenha criado uma barra em cima de foo, mas você criou o baz nesse meio tempo e depois se fundiu, fornecendo um histórico de

$ git lola
* 2582152 (HEAD, mestre) Mesclar ramificação 'otherguy'
| \  
| * barra c7256de (otherguy)
* b7e7176 baz
| /  
* 9968f79 foo

Nota: git lola é um alias não padrão, mas útil.

Nenhum dado com git revert:

$ git revert HEAD
fatal: confirmar 2582152 ... é uma mesclagem, mas nenhuma opção -m foi fornecida.

Charles Bailey deu uma excelente resposta, como sempre. Usando git revertcomo em

$ git revert --no-edit -m 1 CABEÇA
[master e900aad] Reverter "Mesclar ramo 'otherguy'"
 0 arquivos alterados, 0 inserções (+), 0 exclusões (-)
 modo de exclusão 100644 bar

efetivamente exclui bare produz um histórico de

$ git lola
* e900aad (HEAD, mestre) Reverter "Merge branch 'otherguy'"
* 2582152 Mesclar ramificação 'otherguy'
| \  
| * barra c7256de (otherguy)
* b7e7176 baz
| /  
* 9968f79 foo

Mas suspeito que você deseja jogar fora o commit de mesclagem:

$ git reset --hard HEAD ^
HEAD está agora no b7e7176 baz

$ git lola
* b7e7176 (HEAD, mestre) baz
| * barra c7256de (otherguy)
| /  
* 9968f79 foo

Conforme documentado no git rev-parsemanual

<rev>^, por exemplo, HEAD ^,v1.5.1^0
Um sufixo ^para um parâmetro de revisão significa o primeiro pai desse objeto de confirmação. ^<n>significa o n- ésimo pai ( ie <rev>^ é equivalente a <rev>^1). Como regra especial, <rev>^0significa a confirmação em si e é usado quando <rev>é o nome do objeto de uma tag que se refere a um objeto de confirmação.

portanto, antes de chamar git reset, HEAD^(ou HEAD^1) era b7e7176 e HEAD^2c7256de, ou seja , respectivamente o primeiro e o segundo pais da consolidação de mesclagem.

Tenha cuidado, git reset --hardpois pode destruir o trabalho.

Greg Bacon
fonte
3
É um mundo confuso, confuso e abalado. Exceto por Lola. Um milhão de agradecimentos por este alias fantástico.
Barney
Maneira fácil de adicionar lolaaos seus comandos git:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
D. Gibbs
8

Eu tive esse problema, a solução era olhar para o gráfico de confirmação (usando o gitk) e ver se eu tinha o seguinte:

*   commit I want to cherry-pick (x)
|\  
| * branch I want to cherry-pick to (y)
* | 
|/  
* common parent (x)

Eu entendo agora que eu quero fazer

git cherry-pick -m 2 mycommitsha

Isso ocorre porque -m 1seria mesclado com base no pai comum, onde, como -m 2mesclas com base no ramo y, é para o qual eu quero escolher.

shmish111
fonte
1
Possivelmente porque não está relacionado git-revert, o que é essa questão.
Pnomolos # 9/16
1
Eu acho que essa pergunta é sobre a -mopção, não exclusivamente sobre git merge. Ou seja, o raciocínio por trás do uso da -mopção parece ser semelhante para os reversos e escolhas de cereja. Se isso não for verdade, informe-nos. Como não encontrei outras perguntas que abordem especificamente o uso escolhido por ele, agradeço por esta resposta, que provavelmente levou o Google a me ajudar a encontrar essa pergunta e a uma discussão útil e relevante!
N181 # n183 # 15: