Änderung in Git rückgängig machen (Verlauf nicht umschreiben)

Lesezeit: 8 Minuten

Anderung in Git ruckgangig machen Verlauf nicht umschreiben
dbr

Ich habe eine Änderung in einem Skript vorgenommen und sie übernommen. Dann habe ich ein paar andere Änderungen vorgenommen und sie in ein Remote-Repository und dergleichen verschoben.

Dann wurde mir klar, dass die erste Änderung, die ich erwähnte, dumm war und sie rückgängig machen wollte.

Als Beispiel: Ich habe zwei Dateien, a.py und b.py:

Commit 1:
I delete a function in a.py

Commit 2:
I change a few lines in b.py

Commit 3:
I change the docstring in a.py

Kann ich das Löschen dieser Funktion rückgängig machen und es als “Commit 4” erscheinen lassen (anstatt Commit 1 zu löschen)

  • Oi, es ist “realisiert”, nicht “realisiert”! (Ich bin kein Amerikaner..)

    – dbr

    13. März 09 um 11:48 Uhr

  • Ihre Rechtschreibung wurde von einem Volk korrigiert, das Meter und Füße verwendet, um Dinge zu messen … ha ha

    – Tür

    22. November 13 um 7:31 Uhr

1644073147 681 Anderung in Git ruckgangig machen Verlauf nicht umschreiben
Jess Rusak

Ja, können Sie verwenden git zurücksetzen dafür. Siehe die git Handbuchabschnitt dazu für mehr Informationen.

Das Wesentliche ist, dass Sie sagen können:

git revert 4f4k2a

Wobei 4f4k2a die ID des Commit ist, das Sie rückgängig machen möchten, und es wird versuchen, es rückgängig zu machen.

  • Übrigens! Es wird dieses Commit-1-Objekt löschen

    – aatifh

    13. März 09 um 11:51 Uhr

  • Ich glaube nicht, dass Sie den Commit aus dem Verlauf löschen können, aber Sie können die Änderung rückgängig machen.

    – Jeremy French

    13. März 09 um 12:04 Uhr

  • Ich nehme an, Git ist so fortgeschritten, dass Benutzer etwas so Einfaches wie ein Zurücksetzen vergessen würden … lol 😛

    – chakrit

    14. März 09 um 20:52 Uhr

Anderung in Git ruckgangig machen Verlauf nicht umschreiben
VonC

Nur ein Kommentar:

git revert aCommit

kehrt das zurück alle verpflichten (wie in “alle Dateien Teil des Commit” ):
es berechnet einen Reverse-Patch, wendet es auf HEAD an und übergibt es.

Also zwei Probleme hier (das erste ist leicht zu lösen):

  • es wird immer festgelegt, also möchten Sie vielleicht hinzufügen -no-commit Möglichkeit: “git revert --no-commit aCommit“: Dies ist nützlich, wenn Sie den Effekt von mehr als einem Commit hintereinander auf Ihren Index zurücksetzen.
  • es gilt nicht für eine bestimmte Datei (was ist, wenn Sie a.py Teil eines Commits mit 1000 anderen Änderungen waren, die Sie möglicherweise nicht rückgängig machen möchten)?
    Wenn Sie dafür bestimmte Dateien so extrahieren möchten, wie sie in einem anderen Commit waren, sollten Sie sehen git-checkout, speziell die git checkout <commit> <filename> Syntax (das ist in diesem Fall aber nicht genau das, was Sie brauchen)

Einfaches Git (Elijah Newren) versuchte, einen “vollständigeren Rückschritt” zu erreichen Git-Mailingliste; aber ohne großen erfolg:

Gelegentlich möchten Leute “Änderungen rückgängig machen”.

Das kann nun sein:

  • die Änderungen zwischen 32 und 29 Revisionen vor,
  • es könnten alle Änderungen seit dem letzten Commit sein,
  • es könnten die Änderungen seit 3 ​​Commits sein, oder
  • es könnte nur ein bestimmtes Commit sein.
  • Der Der Benutzer möchte solche Rücksetzungen möglicherweise nur auf bestimmte Dateien beschränken,

(eg revert ist hier dokumentiert, aber ich bin mir nicht sicher, ob es Teil der aktuellen Distribution von eg ist)

aber am Ende läuft alles darauf hinaus, “Änderungen rückgängig zu machen”.

eg revert --since HEAD~3  # Undo all changes since HEAD~3
eg revert --in HEAD~8     # much like git revert HEAD~8, but nocommit by default
eg revert --since HEAD foo.py  # Undo changes to foo.py since last commit
eg revert foo.py               # Same as above
eg revert --in trial~7 bar.c baz.  # Undo changes made in trial~7 to bar.[ch]

Sind diese Arten des “Zurücksetzens von Daten” wirklich so unterschiedlich, dass es unterschiedliche Befehle geben sollte oder dass einige dieser Operationen nicht vom einfachen Zurücksetzen-Befehl unterstützt werden sollten?
Sicher, die meisten Benutzer werden wahrscheinlich die meiste Zeit das “eg revert FILE1 FILE2...“Form, aber ich sah keinen Schaden darin, die zusätzlichen Fähigkeiten zu unterstützen.

Außerdem … gibt es irgendetwas Grundsätzliches, das Core Git davon abhalten würde, ein solches Verhalten anzunehmen?

Elia

Hinweis: Commits machen standardmäßig keinen Sinn für das Generalisierte revert Befehl und “git revert REVISION” würde mit Anweisungen fehlschlagen (die dem Benutzer mitteilen, das –in-Flag hinzuzufügen).


Nehmen wir an, Sie haben von 50 festgeschriebenen 20 Dateien festgestellt, dass das alte Festschreiben X Änderungen eingeführt hat, die nicht hätten stattfinden sollen.
Ein wenig Klempnerarbeit ist in Ordnung.
Was Sie brauchen, ist eine Möglichkeit, alle spezifischen Dateien aufzulisten, die Sie benötigen zurückkehren

(wie in “um in Commit X vorgenommene Änderungen abzubrechen und alle nachfolgenden Änderungen beizubehalten”),
und dann für jeden von ihnen:

git-merge-file -p a.py X X^

Das Problem hier ist, die verlorene Funktion wiederherzustellen, ohne alle nachfolgenden Änderungen in a.py zu löschen, die Sie vielleicht behalten möchten.
Diese Technik wird manchmal als “negatives Zusammenführen” bezeichnet.

Seit git merge-file <current-file> <base-file> <other-file> bedeutet:
enthält alle Änderungen, die von der führen <base-file> zu <other-file> hinein <current-file>, Sie können wiederherstellen die gelöschte Funktion, indem Sie sagen, dass Sie alle Änderungen übernehmen möchten.)

  • aus: X (wo die Funktion gelöscht wurde)
  • to: X^ (das vorherige Commit vor X, wo die Funktion noch da war)

Beachten Sie das -p -Argument, mit dem Sie zuerst die Änderungen überprüfen können, ohne etwas an der aktuellen Datei zu tun. Wenn Sie sicher sind, entfernen Sie diese Option.

Notiz: das git merge-file ist nicht so einfach: Sie können nicht einfach so auf frühere Versionen der Datei verweisen.
(Sie würden immer wieder die frustrierende Nachricht erhalten: error: Could not stat X)
Sie müssen:

git cat-file blob a.py > tmp/ori # current file before any modification
git cat-file blob HEAD~2:a.py > tmp/X # file with the function deleted
git cat-file blob HEAD~3:a.py > tmp/F # file with the function which was still there

git merge-file a.py tmp/X tmp/F # basically a RCS-style merge
                                 # note the inversed commit order: X as based, then F
                                 # that is why is is a "negative merge"
diff -u a.py tmp/ori # eyeball the merge result
git add a.py 
git commit -m "function restored" # and any other changes made from X are preserved!

Wenn dies für eine große Anzahl von Dateien innerhalb eines vorherigen Commits durchgeführt werden soll … ist etwas Skripting angebracht 😉

  • Ich glaube nicht, dass Sie den Bindestrich brauchen in: git checkout <commit> <filename>

    – Paulus

    14. März 09 um 15:52 Uhr

1644073148 560 Anderung in Git ruckgangig machen Verlauf nicht umschreiben
Paul

Um die Änderungen auf nur eine Datei innerhalb eines Commit zurückzusetzen, wie VonC darauf hingewiesen hat, würde ich das tun checkout den Zweig (Master oder Stamm oder was auch immer) und dann checkout die Version der Datei, die ich wiederherstellen und als neuen Commit behandeln wollte:

$ git checkout trunk
$ git checkout 4f4k2a^ a.py
$ git add a.py
$ git diff              #verify I'm only changing what I want; edit as needed
$ git commit -m 'recover function deleted from a.py in 4f4k2a'

Es gibt wahrscheinlich einen Installationsbefehl, der dies direkt tun würde, aber ich würde ihn nicht verwenden, wenn ich ihn wüsste. Es ist nicht so, dass ich Git nicht vertraue, aber ich vertraue mir selbst nicht – ich würde nicht darauf vertrauen, dass ich wüsste, was in dieser Datei bei diesem Commit und seitdem geändert wurde, ohne nachzusehen. Und sobald ich nachgesehen habe, ist es einfacher, einfach einen neuen Commit zu erstellen, indem Sie die bearbeiten diff. Vielleicht ist das nur der persönliche Arbeitsstil.

  • Zwei Kommentare: 1/Wenn die Funktion im 4f4k2a-Commit für a.py gelöscht wurde, sollten Sie a.py nicht auschecken früher verpflichten ? (der Eine Vor 4f4k2a, wie in 4f4k2a^ ?) 2/ Würde das die aktuelle Version von a.py nicht vollständig löschen? Was ist, wenn ich spätere Änderungen beibehalten möchte?

    – VonC

    14. März 09 um 17:47 Uhr

  • Ich würde lieber eine “negative Zusammenführung” mit git-merge-file vornehmen: siehe meine fertige Antwort

    – VonC

    14. März 09 um 17:48 Uhr

  • 1) Ja. Danke für die Korrektur des anderen Tippfehlers. 2) Ja – Deshalb müsste ich den Unterschied sehen. Ich würde tatsächlich ein gehacktes Diffmerge im 3-Wege-Merge-Modus verwenden, was mir ein nützlicheres Diff zeigt, mit dem ich gewöhnt bin, aber Git Diff ist verwendbar. Der Punkt ist: Ich bin nur zuversichtlich, wenn ich mir den Code angesehen habe.

    – Paulus

    14. März 09 um 20:22 Uhr

  • 3) Ja, ich denke, “negatives Zusammenführen” würde funktionieren. Aber mir kostet die Recherche zu viel Zeit, wenn ich weiß, dass ich den Code lesen und schnell den korrigierenden Commit machen kann. Ich glaube, ich habe git-merge-file in zwei anderen SO-Antworten verwendet, wo nichts anderes funktionieren würde, aber es ist nicht wirklich in meinem täglichen Gebrauch.

    – Paulus

    14. März 09 um 20:33 Uhr

  • Ich habe gerade den Anwendungsfall git merge-file in meiner Antwort hinzugefügt (siehe Ende) … dieser Befehl ist nicht einfach zu verwenden: Sie können nicht einfach auf eine frühere Version einer Datei verweisen, Sie müssen in eine temporäre Datei kategorisieren. Das ist eine Enttäuschung…

    – VonC

    15. März 09 um 1:45 Uhr

Anderung in Git ruckgangig machen Verlauf nicht umschreiben
Mohan Nayaka

Sehen Sie sich diese Git-Revert-Frage an. Es scheint ein Problem beim Zurücksetzen älterer Commits zu geben, wenn sie nicht in einer aufeinanderfolgenden Sequenz einschließlich des neuesten Commits sind.

.

784520cookie-checkÄnderung in Git rückgängig machen (Verlauf nicht umschreiben)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy