it-swarm.com.de

Wie bearbeite ich eine falsche Commit-Nachricht in Git (die ich gepusht habe)?

Ich möchte eine Commit-Nachricht ändern, die sich in der Vergangenheit befindet, und ich habe viele neue Commits durchgeführt.

Wie ändere ich die Commit-Nachricht? Ist es möglich?

149
Jimmy

Die Nachricht von Linus Torvalds könnte Ihre Frage beantworten:

Alte Commit-Nachrichten ändern/bearbeiten

Kurze Antwort: Sie können nicht (wenn gedrückt).


auszug (Linus bezeichnet BitKeeper als BK):

Randnotiz, nur aus historischem Interesse: in BK könnte man.

Und wenn Sie daran gewöhnt sind (wie ich), war es wirklich sehr praktisch. Ich würde eine Patch-Bombe von Andrew anwenden, bemerken, dass etwas nicht stimmt, und es einfach bearbeiten, bevor ich es rausschiebe.

Ich hätte dasselbe mit git machen können. Es wäre einfach genug gewesen, nur die Festschreibungsnachricht nicht Teil des Namens zu sein und dennoch zu garantieren, dass der Verlauf unberührt blieb, und die Sache "Kommentare später korrigieren" zuzulassen.

Aber ich habe es nicht getan.

Ein Teil davon ist reine "innere Konsistenz". Git ist einfach ein saubereres System, da alles SHA1-geschützt ist und alle Objekte unabhängig vom Objekttyp gleich behandelt werden. Ja, es gibt vier verschiedene Arten von Objekten, und sie sind alle sehr unterschiedlich. Sie können nicht auf die gleiche Weise verwendet werden, aber gleichzeitig, auch wenn ihre Codierung auf der Festplatte unterschiedlich sein könnte. konzeptionell arbeiten sie alle genau gleich.

Interne Konsistenz ist jedoch keine Entschuldigung dafür, unflexibel zu sein, und es wäre natürlich sehr flexibel, wenn wir Fehler einfach beheben könnten, nachdem sie aufgetreten sind. Das ist also kein wirklich starkes Argument.

Der wahre Grund, warum Sie die Commit-Nachricht nicht ändern können, ist sehr einfach: Auf diese Weise können Sie den Nachrichten vertrauen. Wenn Sie zulassen, dass Personen sie später ändern, sind die Nachrichten von Natur aus nicht sehr vertrauenswürdig.


Um vollständig zu sein, können Sie Ihren lokalen Festschreibungsverlauf umschreiben, um zu reflektieren, was Sie wollen, wie vorgeschlagen von sykora (mit ein bisschen rebase und reset --hard, keuch!)

Sobald Sie jedoch Ihren überarbeiteten Verlauf erneut veröffentlichen (mit einem git Push Origin +master:master, das + Zeichen, das den Push erzwingt, auch wenn dies nicht zu einem "schnellen Vorlauf" führt) ... Sie könnten in Schwierigkeiten geraten .

Auszug aus dieser anderen SO Frage:

Ich habe tatsächlich einmal mit --force zum git.git-Repository gedrängt und wurde von Linus BIG TIME beschimpft. Es wird eine Menge Probleme für andere Menschen schaffen. Eine einfache Antwort lautet "Tu es nicht".

125
VonC

Momentan könnte ein git replace den Trick machen.

Im Detail: Erstellen Sie einen temporären Arbeitszweig

git checkout -b temp

Setzen Sie das Commit zurück, um es zu ersetzen

git reset --hard <sha1>

Ändern Sie das Commit mit der richtigen Meldung

git commit --amend -m "<right message>"

Ersetzen Sie das alte Commit durch das neue

git replace <old commit sha1> <new commit sha1>

geh zurück zu der Filiale, in der du warst

git checkout <branch>

entfernen Sie den temporären Zweig

git branch -D temp

Drücken

guess

getan.

26
Johan

Sie können git rebase -i (gegen den Zweig, von dem Sie abgezweigt sind) 'i' für interaktive.

Ersetzen Sie das pick neben dem zu ändernden Festschreibungskommentar durch r (oder reword), speichern Sie und beenden Sie es. Anschließend können Sie die Bearbeitung vornehmen .

git Push noch einmal und du bist fertig!

17
Marcus

Angenommen, Sie haben einen Baum wie diesen:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]

Zuerst checkout ein temporärer Zweig:

git checkout -b temp

In der temp-Verzweigung reset --hard Zu einem Commit, dessen Nachricht Sie ändern möchten (das Commit lautet beispielsweise 946992):

git reset --hard 946992

Verwenden Sie amend, um die Nachricht zu ändern:

git commit --amend -m "<new_message>"

Danach sieht der Baum so aus:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            b886a0 [temp]

Dann cherry-pick Alle Festschreibungen, die vor 946992 Liegen, von master bis temp und festschreiben, verwenden Sie amend, wenn Sie möchten ändere auch ihre Nachrichten:

git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>

Der Baum sieht nun so aus:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
               \
                b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]

Drücken Sie nun den temporären Zweig auf Remote:

git Push --force Origin temp:master

Im letzten Schritt löschen Sie die Verzweigung master auf local, git fetch Origin, Um die Verzweigung master vom Server abzurufen. Wechseln Sie dann zur Verzweigung master und löschen Sie die Verzweigung temp.

Jetzt werden sowohl Ihre lokale als auch die entfernte Station alle Nachrichten aktualisiert.

13
Huy Vo

In unserem Shop habe ich die Konvention eingeführt, erkennbar benannte annotierte Tags zu Commits mit falschen Nachrichten hinzuzufügen und die Annotation als Ersatz zu verwenden.

Auch wenn dies Leuten, die gelegentliche "git log" -Befehle ausführen, nicht hilft, bietet es uns eine Möglichkeit, falsche Bug-Tracker-Referenzen in den Kommentaren zu korrigieren, und alle meine Build- und Release-Tools verstehen die Konvention.

Dies ist offensichtlich keine generische Antwort, aber es könnte etwas sein, das die Leute innerhalb bestimmter Gemeinschaften übernehmen können. Ich bin sicher, wenn dies in größerem Maßstab verwendet wird, könnte irgendwann eine Art Porzellanträger dafür auftauchen ...

5

(Aus http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c )

Wie man Veränderungen begeht, liegt tiefer in der Geschichte

Da der Verlauf in Git unveränderlich ist, müssen Sie den Verlauf aus dem geänderten Commit und Forward neu schreiben, um alle Änderungen außer dem letzten Commit (Commit, bei dem es sich nicht um einen Zweigkopf handelt) vorzunehmen.

Sie können StGIT dafür verwenden, den Zweig bei Bedarf initialisieren, die Festschreibung, die Sie ändern möchten, aufheben, bei Bedarf darauf zugreifen, eine Änderung vornehmen und den Patch aktualisieren (mit der Option -e, wenn Sie die Festschreibungsmeldung korrigieren möchten) und dann Push alles und stg verpflichten.

Oder Sie können Rebase verwenden, um das zu tun. Erstellen Sie einen neuen temporären Zweig, spulen Sie ihn mit git reset --hard auf das Commit zurück, das Sie ändern möchten, ändern Sie den Commit (er würde über dem aktuellen Kopf liegen), und setzen Sie dann den Zweig mit git rebase --onto auf das geänderte Commit zurück.

Oder Sie können git rebase - interactive verwenden, mit dem Sie verschiedene Modifikationen vornehmen können, z.

Ich denke, das sollte deine Frage beantworten. Beachten Sie jedoch, dass, wenn Sie Code in ein Remote-Repository verschoben haben und die Benutzer davon abgerufen haben, dies ihre Codeverläufe durcheinander bringt, wie ebenso wie die Arbeit, die sie geleistet haben. Also mach es vorsichtig.

2
sykora