250 votes

Pourquoi git revert se plaint-il de l'absence de l'option -m ?

Je travaille donc sur un projet avec d'autres personnes, et il y a plusieurs forks github sur lesquels on travaille. Quelqu'un vient de corriger un problème et j'ai fusionné avec son fork, mais je me suis ensuite rendu compte que je pouvais trouver une meilleure solution. Je veux revenir sur le commit que je viens de faire. J'ai essayé de le faire avec git revert HEAD mais cela m'a donné cette erreur :

fatal: Commit <SHA1> is a merge but no -m option was given.

Qu'est-ce que ça veut dire ? Quand j'ai fusionné et commis, j'ai utilisé l'option -m pour dire "Merged with <username>".

Qu'est-ce que je fais de mal ici ?

304voto

Charles Bailey Points 244082

Par défaut git revert refuse de revenir sur un commit de fusion car ce que cela signifie réellement est ambigu. Je présume que votre HEAD est en fait un commit de fusion.

Si vous voulez revenir sur le commit de fusion, vous devez spécifier quel parent de la fusion vous voulez considérer comme le tronc principal, c'est-à-dire ce vers quoi vous voulez revenir.

Souvent, ce sera le parent numéro un, par exemple si vous étiez sur master et a fait git merge unwanted et a ensuite décidé de revenir sur la fusion de unwanted . Le premier parent serait votre pré-fusion master et le deuxième parent serait l'extrémité du unwanted .

Dans ce cas, vous pourriez le faire :

git revert -m 1 HEAD

git cat-file -p [MERGE_COMMIT_ID] montrera les branches parentes dans l'ordre. La première listée serait -m 1, la seconde -m 2.

56voto

Greg Bacon Points 50449

Disons que l'autre type a créé bar par-dessus foo, mais que vous avez créé baz entre-temps et que vous avez ensuite fusionné, ce qui donne un historique de

$ git lola
\*   2582152 (HEAD, master) Merge branch 'otherguy'
|\\  
| \* c7256de (otherguy) bar
\* | b7e7176 baz
|/  
\* 9968f79 foo

Note : git lola est un alias non standard mais utile.

Aucun résultat avec git revert :

$ git revert HEAD
fatal: Commit 2582152... is a merge but no -m option was given.

Charles Bailey a donné une excellente réponse comme d'habitude. Utilisation de git revert dans le cas de

$ git revert --no-edit -m 1 HEAD
\[master e900aad\] Revert "Merge branch 'otherguy'"
 0 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 bar

supprime effectivement bar et produit une histoire de

$ git lola
\* e900aad (HEAD, master) Revert "Merge branch 'otherguy'"
\*   2582152 Merge branch 'otherguy'
|\\  
| \* c7256de (otherguy) bar
\* | b7e7176 baz
|/  
\* 9968f79 foo

Mais je soupçonne que vous voulez jeter le commit de fusion :

$ git reset --hard HEAD^
HEAD is now at b7e7176 baz

$ git lola
\* b7e7176 (HEAD, master) baz
| \* c7256de (otherguy) bar
|/  
\* 9968f79 foo

Comme l'indique le document git rev-parse manuel

<rev>^ par exemple, HEAD^, v1.5.1^0
Un suffixe ^ à un paramètre de révision signifie le premier parent de cet objet commit. ^<n> signifie que n -e parent ( c'est-à-dire <rev>^ est équivalent à <rev>^1 ). C'est une règle particulière, <rev>^0 signifie l'engagement lui-même et est utilisé lorsque <rev> est le nom d'un objet balise qui fait référence à un objet commit.

donc avant d'invoquer git reset , HEAD^ (ou HEAD^1 ) était b7e7176 et HEAD^2 était c7256de, c'est-à-dire respectivement le premier et le second parent du commit de fusion.

Soyez prudent avec git reset --hard parce que ça peut détruire le travail.

9voto

shmish111 Points 660

J'ai eu ce problème, la solution a été de regarder le graphe de commit (en utilisant gitk) et de voir que j'avais ce qui suit :

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

Je comprends maintenant que je veux faire

git cherry-pick -m 2 mycommitsha

Cela s'explique par le fait que -m 1 fusionneraient sur la base d'un parent commun alors que -m 2 fusionne sur la branche y, c'est celle vers laquelle je veux faire un cherry-pick.

2voto

Maarten Folkers Points 61

Dans la question initiale, l'option '-m' de l'erreur git a probablement été confondue avec un message de validation. Comme expliqué dans les autres réponses, utilisez '-m n' pour spécifier le nième parent de la fusion afin de choisir le parent que vous considérez comme le tronc principal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X