Warum beschwert sich git revert über eine fehlende Option -m?

183

Also arbeite ich mit anderen Leuten an einem Projekt und es werden mehrere Github-Gabeln bearbeitet. Jemand hat gerade ein Problem behoben und ich habe mich mit seiner Gabel zusammengeschlossen, aber dann wurde mir klar, dass ich eine bessere Lösung finden konnte. Ich möchte das soeben vorgenommene Commit zurücksetzen. Ich habe versucht, dies mit zu tun, git revert HEADaber es gab mir diesen Fehler:

fatal: Commit <SHA1> ist eine Zusammenführung, es wurde jedoch keine Option -m angegeben.

Was bedeutet das? Beim Zusammenführen und Festschreiben habe ich die Option -m verwendet, um "Zusammengeführt mit <Benutzername>" zu sagen.

Was mache ich hier falsch?

icnhzabot
quelle

Antworten:

215

Standardmäßig git revertweigert sich, ein Zusammenführungs-Commit zurückzusetzen, da das, was dies tatsächlich bedeutet, nicht eindeutig ist. Ich gehe davon aus, dass es sich bei Ihrem HEADtatsächlich um ein Merge-Commit handelt.

Wenn Sie das Zusammenführungs-Commit zurücksetzen möchten, müssen Sie angeben, welches übergeordnete Element der Zusammenführung Sie als Haupt-Trunk betrachten möchten, dh auf was Sie zurücksetzen möchten.

Oft wird diese Mutter Nummer eins, zum Beispiel, wenn Sie sind auf masterund taten git merge unwantedund dann die Zusammenführung von zurückzukehren entschieden unwanted. Das erste übergeordnete Element wäre Ihr masterZweig vor dem Zusammenführen und das zweite übergeordnete Element wäre die Spitze von unwanted.

In diesem Fall könnten Sie Folgendes tun:

git revert -m 1 HEAD
CB Bailey
quelle
4
OK danke. Ich fand es einfacher, nur die beiden Dateien zu ändern, die von der Zusammenführung betroffen waren, und dann auch einige meiner anderen Änderungen zu übernehmen.
icnhzabot
42
Wo finde ich Informationen, ob ich -m1 oder -m2 verwenden muss, ...?
Patrick Cornelissen
34
git cat-file -p [MERGE_COMMIT_ID]zeigt die übergeordneten Zweige der Reihe nach an. Der erste wäre -m 1der zweite -m 2.
Nostromo
2
git revert [HASH] -m 2sagt mir Auf Zweig 1.x-1.x gibt es nichts zu festschreiben, Arbeitsverzeichnis sauber, aber mein Festschreiben wird nicht zurückgesetzt.
Jenlampton
3
Wenn ich also die letzten 10 Zusammenführungen zurücksetzen muss (was sehr wahrscheinlich ist, da git jedes Mal, wenn ich Änderungen von einem anderen Entwickler einnehme, automatisch eine Zusammenführung durchführt), muss ich dies für jede einzelne Zusammenführung tun? Ist das der Grund, warum Git-Fans so scharf auf Rebasing sind, weil Revert im Grunde genommen nutzlos ist?
Neutrino
45

Angenommen, der andere Typ hat eine Leiste über foo erstellt, aber Sie haben in der Zwischenzeit baz erstellt und sich dann zusammengeschlossen, um eine Geschichte von zu geben

$ git lola
* 2582152 (HEAD, Master) Zweig 'otherguy' zusammenführen
| \  
| * c7256de (otherguy) bar
* | b7e7176 baz
| /  
* 9968f79 foo

Hinweis: Git Lola ist ein nicht standardmäßiger, aber nützlicher Alias.

Keine Würfel mit git revert:

$ git KOPF zurücksetzen
fatal: Commit 2582152 ... ist eine Zusammenführung, aber es wurde keine Option -m angegeben.

Charles Bailey gab wie immer eine ausgezeichnete Antwort . Verwenden git revertwie in

$ git revert --no-edit -m 1 HEAD
[master e900aad] "Zweig 'otherguy' zusammenführen"
 0 Dateien geändert, 0 Einfügungen (+), 0 Löschungen (-)
 Löschmodus 100644 bar

effektiv löscht barund produziert eine Geschichte von

$ git lola
* e900aad (HEAD, Master) "Zweig 'otherguy' zusammenführen"
* 2582152 Zweig 'otherguy' zusammenführen
| \  
| * c7256de (otherguy) bar
* | b7e7176 baz
| /  
* 9968f79 foo

Aber ich vermute, Sie möchten das Merge-Commit wegwerfen :

$ git reset --hard HEAD ^
HEAD ist jetzt bei b7e7176 baz

$ git lola
* b7e7176 (KOPF, Meister) baz
| * c7256de (otherguy) bar
| /  
* 9968f79 foo

Wie im Handbuch dokumentiertgit rev-parse

<rev>^Beispiel: HEAD ^,v1.5.1^0
Ein Suffix ^zu einem Revisionsparameter bedeutet das erste übergeordnete Element dieses Festschreibungsobjekts. ^<n>bedeutet das n- te Elternteil ( dh <rev>^ entspricht äquivalent zu <rev>^1). In der Regel <rev>^0bedeutet dies das Festschreiben selbst und wird verwendet, wenn <rev>der Objektname eines Tag-Objekts auf ein Festschreibungsobjekt verweist.

Vor dem Aufrufen git resetwar HEAD^(oder HEAD^1) also b7e7176 und HEAD^2war c7256de, dh der erste und der zweite Elternteil des Merge-Commits.

Seien Sie vorsichtig, git reset --hardda dies die Arbeit zerstören kann.

Greg Bacon
quelle
3
Es ist eine durcheinandergebrachte, durcheinandergebrachte, durcheinandergebrachte Welt. Außer Lola. Vielen Dank für diesen fantastischen Alias.
Barney
Einfache Möglichkeit, lolaIhre Git-Befehle zu ergänzen:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
D. Gibbs
8

Ich hatte dieses Problem. Die Lösung bestand darin, das Commit-Diagramm (mit gitk) zu überprüfen und festzustellen, dass ich Folgendes hatte:

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

Ich verstehe jetzt, dass ich tun möchte

git cherry-pick -m 2 mycommitsha

Dies liegt daran, dass -m 1die Zusammenführung auf der Grundlage des gemeinsamen übergeordneten -m 2Elements erfolgen würde, wobei die Zusammenführung auf der Grundlage des Zweigs y diejenige ist, für die ich eine Auswahl treffen möchte.

shmish111
quelle
1
Möglicherweise, weil es nicht damit zusammenhängt git-revert, worum es bei dieser Frage geht.
Pnomolos
1
Ich denke, bei dieser Frage geht es um die -mOption, nicht ausschließlich um git merge. Das heißt, die Gründe für die Verwendung der -mOption scheinen für Reverts und Cherry-Picks ähnlich zu sein. Wenn das nicht stimmt, lassen Sie es uns bitte wissen. Da ich keine anderen Fragen gefunden habe, die sich speziell mit der Verwendung von Kirschen befassen, danke für diese Antwort, die wahrscheinlich dazu geführt hat, dass Google mir geholfen hat, diese Frage und nützliche, relevante Diskussion zu finden!
Nealmcb