Git: Wie kann ich die Nachricht eines Merge-Commits bearbeiten / umformulieren?

147

Wie bearbeite oder formuliere ich die Nachricht eines Zusammenführungs-Commits neu?

git commit --amendfunktioniert, wenn es das letzte Commit ist ( HEAD), aber was ist, wenn es vorher kommt HEAD?

git rebase -i HEAD~5 listet die Zusammenführungs-Commits nicht auf.

ma11hew28
quelle

Antworten:

206

Wenn Sie dem Befehl die --preserve-mergesOption (oder das Synonym -p) hinzufügen , git rebase -iversucht git, die Zusammenführungen beim erneuten Basieren beizubehalten, anstatt den Verlauf zu linearisieren, und Sie sollten auch in der Lage sein, die Zusammenführungs-Commits zu ändern:

git rebase -i -p HEAD~5
Mark Longair
quelle
1
Ich habe dies getan, aber nachdem ich meine Änderungen vorgenommen habe und ich versuche, meine Änderungen zu beschleunigen, bekomme ich dies! [rejected] HEAD -> master (non-fast-forward)error: failed to push some refs to
Marc
1
Versuchen Sie, git push -f und dann Ihren Ursprungszweig auszuführen. das sollte funktionieren. Ich hatte das gleiche Problem, aus irgendeinem Grund ist dies ein Artefakt der Neubasierung, da im Grunde genommen nach der Neubasierung eine abgetrennte Hecke entstanden ist, sodass die -force dies beheben und alles vorantreiben sollte.
Radu Comaneci
11
@Marc Dies geschieht, weil Sie bereits gesendete Commits geändert haben. Es wird als schlechte Praxis angesehen, Push auf einen Server zu erzwingen, da dies Sie und Ihre Mitarbeiter vollständig desynchronisieren kann. Nun, wenn Sie alleine sind, sollte es kein Problem sein.
Ibizaman
Wo HEAD~5ist das übergeordnete Element des Commits, das Sie ändern möchten (normalerweise sha1 ^)?
Gabriel Devillers
2
--preserve-mergesist jetzt--rebase-merges
OrangeDog
32

Beachten Sie, dass beim Starten von git1.7.9.6 (und git1.7.10 +) git mergeselbst immer der Editor ausgelöst wird , damit Sie einer Zusammenführung Details hinzufügen können.

" git merge $tag" Zum Zusammenführen eines mit Anmerkungen versehenen Tags wird der Editor immer während einer interaktiven Bearbeitungssitzung geöffnet. In der v1.7.10-Serie wurde eine Umgebungsvariable GIT_MERGE_AUTOEDIT eingeführt, um älteren Skripten dabei zu helfen, dieses Verhalten abzulehnen. Der Wartungspfad sollte dies jedoch auch unterstützen.

Außerdem wird eine Umgebungsvariable eingeführt, GIT_MERGE_AUTOEDITmit der ältere Skripte dieses Verhalten ablehnen können.

Siehe " Git 1.7.10 antizipieren ":

Kürzlich gab Linus in einer Diskussion auf der Git-Mailingliste zu (und ich stimmte zu), dass dies einer der Designfehler war, die wir zu Beginn der Geschichte von Git gemacht haben.
Und in Version 1.7.10 und höher öffnet der Befehl git merge, der in einer interaktiven Sitzung ausgeführt wird (dh sowohl die Standardeingabe als auch die mit einem Terminal verbundene Standardausgabe), einen Editor, bevor ein Commit zum Aufzeichnen des Zusammenführungsergebnisses erstellt wird Der Benutzer hat die Möglichkeit, die Zusammenführung zu erklären, genau wie der Befehl git commit, den der Benutzer nach dem Lösen einer in Konflikt stehenden Zusammenführung bereits ausführt.

Linus sagte:

Aber es ist mir eigentlich egal, wie es tatsächlich funktioniert - mein Hauptproblem ist, dass Git es viel zu einfach macht, schlechte Zusammenführungsnachrichten zu haben.
Ich denke, ein Teil davon ist eine noch einfachere Idiotie: Wir starten den Editor standardmäßig nicht einmal für eine "Git-Zusammenführung", sondern für eine " git commit".
Das war ein Designfehler und bedeutet, dass Sie zusätzliche Arbeit leisten müssen, wenn Sie einer Zusammenführung tatsächlich eine Notiz hinzufügen möchten. Die Leute also nicht
.


Beachten Sie, dass vor Git 2.17 (Q2 2018) " git rebase -p" Protokollnachrichten eines Zusammenführungs-Commits entstellt wurden, das jetzt behoben ist.

Siehe Commit ed5144d (08. Februar 2018) von Gregory Herrero (``) .
Vorgeschlagen von: Vegard Nossum ( vegard) und Quentin Casasnovas ( casasnovas) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 8b49408 , 27. Februar 2018)

rebase -p: Behebung einer falschen Festschreibungsnachricht beim Aufrufen git merge.

Seit Commit dd6fb00 (" rebase -p: Quoting beim Aufruf git mergekorrigieren", Januar 2018, Git 2.16.0-rc2) wird die Commit-Nachricht des neu basierten Merge-Commits mit einer Subshell, die ' git rev-parse --sq-quote' ausführt, an den Merge-Befehl übergeben .

Um diese Unterschale sind doppelte Anführungszeichen erforderlich, damit Zeilenumbrüche für den git mergeBefehl beibehalten werden .

Vor diesem Patch folgende Zusammenführungsnachricht:

"Merge mybranch into mynewbranch

Awesome commit."

wird:

"Merge mybranch into mynewbranch Awesome commit."

nach a rebase -p.


Mit Git 2.23 (Q2 2019) sollte eine merge -cAnweisung " " während " git rebase --rebase-merges" dem Benutzer die Möglichkeit geben, die Protokollnachricht zu bearbeiten, auch wenn ansonsten keine neue Zusammenführung erstellt und die vorhandene ersetzt werden muss (dh stattdessen ein schneller Vorlauf) ), aber nicht.
Welches wurde korrigiert.

Siehe Commit 6df8df0 (02. Mai 2019) von Phillip Wood ( phillipwood) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit c510261 , 13. Juni 2019)

VonC
quelle
16

Eine weitere nette Antwort, die nur primitive Befehle verwendet - von knittl https://stackoverflow.com/a/7599522/94687 :

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

oder ein besserer (korrekterer) endgültiger Rebase-Befehl:

git rebase <sha of merge> previous_branch --onto HEAD

Übrigens könnte die Verwendung der primitiven Befehle die nette "Funktion" haben, nicht zu viel CPU zu verbrauchen und Sie unbekannte Zeit warten zu lassen, bis Git mit dem Nachdenken über die Liste der Commits fertig ist, die im Fall von neu basiert werden müssen git rebase -p -i HEAD^^^^ (ein solcher Befehl, der dazu führen würde) Eine Liste von nur 4 letzten Commits mit der Zusammenführung als letzte in meinem Fall in meinem Fall dauerte ungefähr 50 Sekunden!).

imz - Ivan Zakharyaschev
quelle
2
Das ist wirklich nützlich, sparen Sie mir ziemlich viel Zeit. Mein Unternehmen blockiert einige Commit-Nachrichten im Repository, was mit --amend- oder Rebase-Befehlen einfach ist, aber: Großes Problem, wenn wir einen Zweig in Ihren zusammenführen, einen Commit durchführen und versuchen zu pushen, wird die Standard-Merge-Nachricht von git blockiert ( Ich weiß, dass dies behoben werden sollte, was uns zwingt, diese Nachricht zu ändern. Bis zu dieser Antwort habe ich viele Dinge versucht, um eine Zusammenführungsnachricht zwischen einer Geschichte von Commits ohne Erfolg zu ändern.
Giovanni Silva
2

git merge --edit
Ermöglicht es Ihnen, den Kommentar auch bei nicht interaktiver Zusammenführung abzugeben.

git merge --edit --no-ff Dies kann nützlich sein, wenn Sie dem Git-Flow folgen, indem Sie den Entwicklungszweig neu gründen und ohne schnellen Vorlauf in ihn einbinden.

Neu machen
quelle
2

Für aktuelle Git-Versionen (Mai 2020):

git rebase -i -r <parent>,

dann im Editor merge -C ...durch ersetzen merge -c ....

Dadurch wird die Festschreibungsnachricht während der erneuten Basierung im Editor geöffnet, wo Sie sie ändern können.

(Danke an VonC für den Hinweis .)

Eugen Labun
quelle
0

Der git rebase -i HEAD~5Befehl öffnet den Editor. Es listet die angegebenen Commits auf (in diesem Fall fünf davon). Die erste Spalte enthält pickfür jedes Commit. Ersetzen Sie einfach pickmit rewordin diesem Editor und speichern + schließen Sie den Editor. Dann öffnet git den Editor für jedes Commit, zu dem Sie gewechselt haben pick, rewordund lässt Sie die Commit-Nachricht bearbeiten.

ChrisD
quelle
6
Dies funktioniert nur bei einem Zusammenführungs-Commit, wenn Sie -pdem git rebaseBefehl auch etwas hinzufügen .
Paul Price
4
Gute