3276 Stimmen

Wie kann ich eine bestimmte Übertragung ändern?

Normalerweise reiche ich eine Liste von Übertragungen zur Überprüfung ein. Wenn ich die folgenden Commits habe:

  1. HEAD
  2. Commit3
  3. Commit2
  4. Commit1

...Ich weiß, dass ich Head Commit ändern kann mit git commit --amend . Aber wie kann ich die Commit1 da es sich nicht um die HEAD verpflichten?

52 Stimmen

Eine alternative Antwort finden Sie hier: stackoverflow.com/a/18150592/520567 Die von Ihnen akzeptierte Antwort ist eigentlich eine exakte Antwort auf Ihre Frage, aber wenn Sie Ihren neuen Commit schon fertig haben, bevor Sie sich entschlossen haben, edit zu verwenden, dann wäre diese Antwort einfacher. Es kann auch mit mehreren Commits funktionieren, die Sie zusammen mit einem älteren Commit zusammenführen/verschmelzen wollen.

7 Stimmen

Sie können auch einfach sehen Aufteilen einer Übertragung en Git-Tools - Geschichte neu schreiben für weitere Informationen.

1 Stimmen

4500voto

ZelluX Punkte 62786

Sie können verwenden Git-Rebase . Wenn Sie zum Beispiel eine Übergabe ändern möchten bbc643cd , laufen

$ git rebase --interactive 'bbc643cd^'

Bitte beachten Sie das Caret ^ am Ende des Befehls, denn Sie müssen tatsächlich zurück zu die Verpflichtung avant die Sie ändern möchten .

Ändern Sie im Standard-Editor pick à edit in der Zeile mit der Angabe "bbc643cd".

Speichern Sie die Datei und beenden Sie sie: Git wird die Befehle in der Datei interpretieren und automatisch ausführen. Sie werden sich in der vorherigen Situation wiederfinden, in der Sie gerade eine Übergabe erstellt hatten bbc643cd .

Zu diesem Zeitpunkt, bbc643cd ist Ihr letzter Commit und Sie können es leicht zu ändern : Nehmen Sie Ihre Änderungen vor und übertragen Sie sie dann mit dem Befehl:

$ git commit --all --amend --no-edit

Danach geben Sie ein:

$ git rebase --continue

um zur vorherigen HEAD-Übertragung zurückzukehren.

WARNUNG : Beachten Sie, dass dadurch der SHA-1-Wert der Übergabe geändert wird. wie auch alle Kinder -- mit anderen Worten, die Geschichte wird von diesem Zeitpunkt an neu geschrieben. Auf diese Weise können Sie Repos zerstören wenn Sie mit dem Befehl git push --force

167 Stimmen

Eine weitere interessante Option innerhalb dieses Ablaufs ist, dass Sie, sobald Sie sich zu dem Commit begeben haben, den Sie ändern wollen, anstatt Dateien zu ändern und den darüber liegenden Commit (den, den Sie gerade bearbeiten) zu überschreiben, diesen Commit vielleicht in zwei verschiedene Commits (oder sogar mehr) aufteilen wollen. In diesem Fall gehen Sie zurück zu dem zu bearbeitenden Commit und führen Sie "git reset HEAD^" aus, um die geänderten Dateien dieses Commits in die Stage zu übernehmen. Nun können Sie beliebige Dateien auswählen und übertragen. Dieser Ablauf ist in der "git-rebase"-Manualseite sehr gut erklärt. Siehe Abschnitt "Splitting commits". bit.ly/d50w1M

249 Stimmen

In Git 1.6.6 und neueren Versionen können Sie die reword Aktion in git rebase -i anstelle von edit (es wird automatisch der Editor geöffnet und mit den restlichen Schritten der Umbasierung fortgefahren; dadurch entfällt die Verwendung von git commit --ammend y git rebase --continue wenn Sie nur die Übergabemeldung und nicht den Inhalt ändern müssen).

1 Stimmen

Vielleicht habe ich eine alte Version von Git, aber meine (Git 1.5.6.5, auf Debian 5, hust hust) erforderte die --interactive Option vor der Revisionsspezifikation. Ich habe die Antwort entsprechend bearbeitet.

782voto

Zaz Punkte 42583

Benutzen Sie die fantastische interaktive Rebase:

git rebase -i @~9   # Show the last 9 commits in a text editor

Finden Sie den gewünschten Commit, ändern Sie pick à e ( edit ), und speichern und schließen Sie die Datei. Git wird zu diesem Commit zurückspulen und Sie können entweder:

  • verwenden. git commit --amend um Änderungen vorzunehmen, oder
  • verwenden. git reset @~ um den letzten Commit zu verwerfen, aber nicht die Änderungen an den Dateien (d.h. Sie werden an den Punkt zurückgebracht, an dem Sie die Dateien bearbeitet, aber noch nicht committed hatten).

Letzteres ist nützlich, um komplexere Dinge wie das Aufteilen in mehrere Commits durchzuführen.

Dann führen Sie git rebase --continue und Git wird die nachfolgenden Änderungen auf der Grundlage Ihrer geänderten Übergabe wiedergeben. Möglicherweise werden Sie aufgefordert, einige Merge-Konflikte zu beheben.

Nota: @ ist die Kurzform für HEAD y ~ ist der Commit vor dem angegebenen Commit.

Lesen Sie mehr über Umschreiben der Geschichte in den Git-Dokumenten.

Scheuen Sie sich nicht, neu zu gründen

ProTip™:   Scheuen Sie sich nicht, mit "gefährlichen" Befehlen zu experimentieren, die die Historie umschreiben* - Git löscht Ihre Commits standardmäßig 90 Tage lang nicht; Sie können sie im Reflog finden:

$ git reset @~3   # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Achten Sie auf Optionen wie --hard y --force Allerdings können sie Daten verwerfen.
* Schreiben Sie auch nicht die Geschichte von Zweigen um, an denen Sie mitarbeiten.


Auf vielen Systemen, git rebase -i wird standardmäßig Vim geöffnet. Vim funktioniert nicht wie die meisten modernen Texteditoren, also schauen Sie sich wie man mit Vim umbasiert . Wenn Sie lieber einen anderen Editor verwenden möchten, ändern Sie ihn mit git config --global core.editor your-favorite-text-editor .

0 Stimmen

Sollte dies für Commits verwendet werden, die bereits in einen entfernten Zweig verschoben wurden?

12 Stimmen

git reset @~ genau das, was ich tun wollte, nachdem ich mich für ein Engagement mit git rebase ... . Du bist mein Held)

4 Stimmen

Für Leute, die die erste Übertragung bearbeiten wollen: git rebase -i --root .

143voto

thrau Punkte 2600

Interaktiv neu gründen con --autosquash ist etwas, das ich häufig verwende, wenn ich frühere Übertragungen tiefer in der Historie korrigieren muss. Es beschleunigt im Wesentlichen den Prozess, den ZelluXs Antwort illustriert, und ist besonders praktisch, wenn Sie mehr als einen Commit haben, den Sie bearbeiten müssen.

Aus der Dokumentation:

--autosquash

Wenn die Commit-Log-Meldung mit "squash! " (oder "fixup! ") beginnt und es einen Commit gibt, dessen Titel mit demselben beginnt, wird die ToDo-Liste von rebase -i automatisch so geändert, dass der Commit, der zum Squash markiert ist, direkt nach dem zu ändernden Commit kommt

Angenommen, Sie haben einen Verlauf, der wie folgt aussieht:

$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1

und Sie haben Änderungen, die Sie an Commit2 anpassen möchten, dann übertragen Sie Ihre Änderungen mit

$ git commit -m "fixup! Commit2"

alternativ können Sie die Commit-sha anstelle der Commit-Nachricht verwenden, also "fixup! e8adec4 oder auch nur ein Präfix der Commit-Nachricht.

Starten Sie dann ein interaktives Rebase für die Übergabe vor

$ git rebase e8adec4^ -i --autosquash

Ihr Editor öffnet sich mit den bereits korrekt geordneten Übertragungen

pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3

alles was Sie tun müssen, ist speichern und beenden

33 Stimmen

Sie können auch Folgendes verwenden git commit --fixup=@~ anstelle von git commit -m "fixup! Commit2" . Dies ist besonders nützlich, wenn Ihre Commit-Nachrichten länger sind und es mühsam wäre, alles abzutippen.

3 Stimmen

Ich habe einen Alias für meine .gitconfig geschrieben, um dies zu vereinfachen fixup = "!fn() { git commit --fixup ${1} && GIT_EDITOR=true git rebase --autosquash -i ${1}^; }; fn -> git fixup <commitId> ändert alle abgestuften Änderungen an der angegebenen Übergabe

1 Stimmen

Danke @thrau! Aber es fehlt ein Abschluss " .

70voto

justMe Punkte 1892

Basierend auf Dokumentation

Ändern der Nachricht älterer oder mehrerer Commit-Nachrichten

git rebase -i HEAD~3 

Das obige Beispiel zeigt eine Liste der letzten 3 Commits auf dem aktuellen Zweig, ändern Sie 3 in etwas anderes, wenn Sie mehr wollen. Die Liste sieht dann ähnlich aus wie die folgende:

pick e499d89 Delete CNAME
pick 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Ersetzen Sie Wählen Sie con umschreiben vor jeder Commit-Nachricht, die Sie ändern möchten. Angenommen, Sie ändern den zweiten Commit in der Liste, dann sieht Ihre Datei wie folgt aus:

pick e499d89 Delete CNAME
reword 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Speichern und schließen Sie die Commit-Liste. Es öffnet sich ein neuer Editor, in dem Sie Ihre Commit-Nachricht ändern können.

Schließlich müssen die geänderten Übertragungen mit Gewalt durchgesetzt werden.

git push --force

0 Stimmen

Ich erhalte die folgende Fehlermeldung: error: Es gab ein Problem mit dem Editor 'vi'. Bitte geben Sie die Meldung entweder mit der Option -m oder -F ein.

3 Stimmen

Die Option "reword" ist ein gutes Werkzeug, aber "git push --force" ist gefährlich. Wenn die Commits, für die wir die Commit-Nachricht ändern wollen, noch nicht übermittelt wurden, ist --force nicht notwendig. Die Option --force überschreibt die Historie des entfernten Reps und erfordert mehr Berechtigungen. Wenn Sie einen Commit ändern wollen, der sich nur auf Ihrem Computer befindet, brauchen Sie --force nicht; wenn der Commit bereits gepusht wurde, sollten Sie ihn nicht ändern, es sei denn, es ist unbedingt notwendig.

62voto

betoharres Punkte 1456

Laufen:

$ git rebase --interactive commit_hash^

jede ^ gibt an, wie viele Commits Sie bearbeiten möchten. Wenn es nur einer ist (der von Ihnen angegebene Commit-Hash), dann fügen Sie nur einen hinzu ^ .

Mit Vim ändern Sie die Wörter pick à reword für die Commits, die Sie ändern wollen, speichern und beenden( :wq ). Dann wird git Sie bei jedem Commit, den Sie als reword markiert haben, fragen, ob Sie die Commit-Nachricht ändern wollen.

Jede Commit-Meldung müssen Sie speichern und beenden( :wq ), um zur nächsten Übergabemeldung zu gelangen

Wenn Sie den Vorgang beenden möchten, ohne die Änderungen zu übernehmen, drücken Sie :q!

EDITAR : zum Navigieren in vim Sie verwenden j nach oben zu gehen, k zu untergehen, h nach links, und l rechts zu gehen( all dies in NORMAL Modus, drücken Sie ESC zu gehen, um NORMAL Modus ). Um einen Text zu bearbeiten, drücken Sie i so dass Sie die INSERT Modus, in dem Sie Text einfügen. Drücken Sie ESC zurückkehren zu NORMAL Modus :)

UPDATE : Hier ist ein toller Link von github listing Wie man (fast) alles mit Git rückgängig macht

4 Stimmen

Hat bei mir perfekt funktioniert. Erwähnenswert git push --force ?

0 Stimmen

Was git push --force überschreibt die Commits des Remotes mit Ihren lokalen Commits. Das ist bei diesem Thema nicht der Fall :)

0 Stimmen

@BetuUuUu natürlich, wenn Ihre Commits an Remote gepusht werden und Sie Commit-Nachricht lokal geändert haben, würden Sie Push an Remote erzwingen wollen, nicht wahr?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X