Verwendung von Git Revert

107

Wie wird git revertverwendet?

Dies mag sich wie eine doppelte Frage anhören, aber wenn Leute sie stellen, lautet die Antwort häufig: Verwenden Sie git resetgemäß Zurücksetzen auf ein Commit durch einen SHA-Hash in Git?

Wenn dann jemand fragt, wie man git resetLeute benutzt, antworten Sie, dass Sie git revertgemäß Git verwenden sollen - wie man zurückrollt

Bevor Sie es wissen, erschienen 8 verschiedene Personen mit ihren eigenen einzigartigen Methoden, um den Arsch des OP zu retten, was alles über Ihrem Kopf liegt.

Versuchen wir also, den Auftrag beizubehalten und einen Dummies-Leitfaden zu schreiben git revert.

Ein Szenario: Sie haben sich zweimal verpflichtet, zu meistern, und es ist schlecht. Sie haben gepusht und andere Leute haben Ihre schlechten Veränderungen.

Sie möchten es rückgängig machen. Es ist nicht etwas, das Sie selbst im Code rückgängig machen können, sagen wir, ein Assistent oder Paketmanager hat überall Unmengen von Dingen geändert - Sie möchten einfach alles wieder so machen, wie es war.

Darum geht es bei der Quellcodeverwaltung. Ich bin sicher, es ist einfach.

Okay, du wirst es benutzen, git revertaber wie?

Und nach dem Laufen git revertmusst du danach noch etwas tun? Müssen Sie die vorgenommenen Änderungen rückgängig machen oder wird die Rückgabe direkt auf das Repo festgeschrieben oder was?

Natürlich müssen Sie erneut pushen und dem Team wahrscheinlich Ihre Bälle mitteilen.

Luke Puplett
quelle

Antworten:

118

git revert macht ein neues Commit

git revert Erstellt einfach ein neues Commit, das das Gegenteil eines vorhandenen Commits ist.

Die Dateien bleiben in demselben Zustand, als ob das zurückgesetzte Commit nie existiert hätte. Betrachten Sie beispielsweise das folgende einfache Beispiel:

$ cd /tmp/example
$ git init
Initialized empty Git repository in /tmp/example/.git/
$ echo "Initial text" > README.md
$ git add README.md
$ git commit -m "initial commit"
[master (root-commit) 3f7522e] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
$ echo "bad update" > README.md 
$ git commit -am "bad update"
[master a1b9870] bad update
 1 file changed, 1 insertion(+), 1 deletion(-)

In diesem Beispiel enthält der Festschreibungsverlauf zwei Festschreibungen, und die letzte ist ein Fehler. Verwenden von git revert:

$ git revert HEAD
[master 1db4eeb] Revert "bad update"
 1 file changed, 1 insertion(+), 1 deletion(-)

Das Protokoll enthält 3 Commits:

$ git log --oneline
1db4eeb Revert "bad update"
a1b9870 bad update
3f7522e initial commit

Es gibt also eine konsistente Historie dessen, was passiert ist, aber die Dateien sind so, als ob das fehlerhafte Update nie stattgefunden hätte:

cat README.md 
Initial text

Es spielt keine Rolle, wo in der Historie das zurückzusetzende Commit ist (im obigen Beispiel wird das letzte Commit zurückgesetzt - jedes Commit kann zurückgesetzt werden).

Fragen schließen

Müssen Sie danach noch etwas tun?

A git revertist nur ein weiteres Commit, z. B. Push auf die Fernbedienung, damit andere Benutzer die Änderungen abrufen / abrufen / zusammenführen können, und Sie sind fertig.

Müssen Sie die vorgenommenen Änderungen rückgängig machen oder wird die Rückgabe direkt auf das Repo festgeschrieben?

git revert ist ein Commit - Es gibt keine zusätzlichen Schritte, vorausgesetzt, Sie möchten ein einzelnes Commit zurücksetzen.

Natürlich müssen Sie erneut pushen und sich wahrscheinlich beim Team melden.

In der Tat - wenn sich die Fernbedienung in einem instabilen Zustand befindet - wäre es richtig, dem Rest des Teams mitzuteilen, dass sie ziehen müssen, um das Problem zu beheben (das Zurücksetzen des Commits) :).

AD7six
quelle
Zur Bestätigung, sowohl für die erste Aussage hier als auch für alle, die sich das Gleiche fragen, was ich gerade gefragt habe, wie es funktioniert, können Sie eine Rücknahme rückgängig machen, bei der es seit der Rücknahme, die Sie zurücksetzen, mehrere neue Commits gibt. Zurücksetzen ist also wirklich nur ein Commit des Gegenteils des zurückgesetzten Commits. Sie könnten natürlich Konflikte haben ... aber das ist eine andere Geschichte.
GG2
Ich finde es immer besser, ein Commit damit zu vermeiden, nur um die Änderungen zuerst zu überprüfen und ich benutze, git revert -n <commitToRevet> oder git revert --no-commit <commitToRevet>
Eklavyaa
2
Ich wollte nur sagen, dass dies nach Jahren des Stackoverflow eine der besten Antworten ist, die mir je begegnet sind. Tolles Beispiel und Erklärung. Danke.
user3344977
Ich bin hierher gekommen und habe erwartet, mehr Informationen zu erhalten, so etwas wie eine TLDR dieses raw.githubusercontent.com/git/git/master/Documentation/howto/…
wviana
1
@wviana Wenn die gefundenen Informationen nicht ausreichen, schreiben Sie bitte eine Antwort. Beachten Sie, dass der Stapelüberlauf kein Ersatz für die offizielle Dokumentation ist (auf die Sie anscheinend verlinken und die einen viel breiteren Bereich als diese Frage abdeckt).
AD7six
35

Verwenden Sie git revert wie folgt:

git revert <insert bad commit hash here>

git revertErstellt ein neues Commit mit den Änderungen, die zurückgesetzt werden. git resetLöscht Ihren Git-Verlauf, anstatt ein neues Commit durchzuführen.

Die folgenden Schritte sind die gleichen wie bei jedem anderen Commit.

Johnny Z.
quelle
Der Unterschied zwischen "Commit zurücksetzen" und "Auf Commit zurücksetzen" ist subtil genug, dass ich jahrelang mit diesem Befehl zu kämpfen habe. Ihre Erklärung hat es für mich sofort gelöst. Vielen Dank!
Claviska
24

Der Grund resetund die revertTendenz, in denselben Gesprächen häufig aufzutreten, liegt darin, dass verschiedene Versionskontrollsysteme sie verwenden, um unterschiedliche Bedeutungen zu haben.

Insbesondere Personen, die an SVN oder P4 gewöhnt sind und nicht festgeschriebene Änderungen an einer Datei wegwerfen möchten, greifen häufig danach, revertbevor ihnen mitgeteilt wird, dass sie dies tatsächlich möchten reset.

In ähnlicher Weise wird das revertÄquivalent in anderen VCS häufig aufgerufen rollbackoder ähnliches - aber "Rollback" kann auch "Ich möchte die letzten Commits vollständig verwerfen" bedeuten, was angemessen ist, resetaber nicht revert. Es gibt also eine Menge Verwirrung, wo die Leute wissen, was sie tun wollen, aber nicht klar sind, welchen Befehl sie dafür verwenden sollen.

Was Ihre eigentlichen Fragen zu ...

Okay, du wirst git revert verwenden, aber wie?

git revert first-bad-commit..last-bad-commit

Und nachdem Sie git revert ausgeführt haben, müssen Sie danach noch etwas tun? Müssen Sie die vorgenommenen Änderungen rückgängig machen oder wird das Zurücksetzen direkt auf das Repo festgeschrieben oder was?

git revertFordert Sie standardmäßig zur Eingabe einer Festschreibungsnachricht auf und schreibt die Ergebnisse fest. Dies kann überschrieben werden. Ich zitiere die Manpage :

--bearbeiten

Mit dieser Option können Sie mit git revert die Festschreibungsnachricht bearbeiten, bevor Sie die Rückgabe festschreiben. Dies ist die Standardeinstellung, wenn Sie den Befehl von einem Terminal aus ausführen.

--no-commit

Normalerweise erstellt der Befehl automatisch einige Commits mit Commit-Protokollnachrichten, die angeben, welche Commits zurückgesetzt wurden. Dieses Flag wendet die Änderungen an, die erforderlich sind, um die benannten Commits auf Ihren Arbeitsbaum und den Index zurückzusetzen, führt jedoch keine Commits durch. Wenn diese Option verwendet wird, muss Ihr Index außerdem nicht mit dem HEAD-Commit übereinstimmen. Das Zurücksetzen erfolgt gegen den Anfangszustand Ihres Index.

Dies ist nützlich, wenn Sie mehr als einen Commit-Effekt hintereinander auf Ihren Index zurücksetzen.

Insbesondere wird standardmäßig für jedes Commit, das Sie zurücksetzen, ein neues Commit erstellt. Sie können revert --no-commitÄnderungen erstellen, die alle zurücksetzen, ohne diese Änderungen als einzelne Festschreibungen festzuschreiben, und dann nach Belieben festschreiben.

ToxicFrog
quelle
git revert first-bad-commit..last-bad-commit: Ich denke das sollte sein git revert parent-of-first-bad-commit..last-bad-commit.
user1071847
9

Die Frage ist ziemlich alt, aber Revert verwirrt immer noch Leute (wie mich)

Als Anfänger habe ich nach einigem Ausprobieren (mehr Fehler als Versuche) einen wichtigen Punkt:

  • git reverterfordert die ID des Commits, das Sie entfernen möchten, um es in Ihrem Verlauf zu behalten

  • git reseterfordert das Commit, das Sie behalten möchten , und entfernt anschließend alles aus dem Verlauf.

Das heißt, wenn Sie revertmit der ersten Commit-ID verwenden, befinden Sie sich in einem leeren Verzeichnis und einem zusätzlichen Commit im Verlauf, während Ihr Verzeichnis beim Zurücksetzen auf das ursprüngliche Commit zurückgesetzt wird und Ihr Verlauf so wird, als ob Die letzten Commits sind nie passiert.

Um noch klarer zu sein, mit einem Protokoll wie diesem:

# git log --oneline

cb76ee4 wrong
01b56c6 test
2e407ce first commit

Wenn Sie verwenden, git revert cb76ee4werden Ihre Dateien standardmäßig auf 01b56c6 zurückgesetzt und Ihrem Verlauf wird ein weiteres Commit hinzugefügt:

8d4406b Revert "wrong"
cb76ee4 wrong
01b56c6 test
2e407ce first commit

git reset 01b56c6 Bringt stattdessen Ihre Dateien zurück zu 01b56c6 und bereinigt danach alle anderen Commits aus Ihrem Verlauf:

01b56c6 test
2e407ce first commit

Ich weiß, dass dies "die Basis" ist, aber es war ziemlich verwirrend für mich, als ich mit der revertersten ID ('first commit') lief. Ich hatte erwartet, meine ursprünglichen Dateien zu finden. Es dauerte eine Weile, bis ich verstanden hatte, dass Sie Ihre Dateien zurück benötigen, wenn Sie sie zurück benötigen Als 'erstes Festschreiben' müssen Sie die nächste ID verwenden.

Unsinn
quelle
Ich habe das gleiche beobachtet. Es ist wirklich verwirrend, aber so wichtig zu wissen. erst kürzlich musste ich einem mitarbeiter helfen und habe das vergessen. Das war ein bisschen peinlich.
ExOfDe
1

Ich habe einige Commits zurückgesetzt, indem ich 'git revert commit id' ausgeführt habe, wie zum Beispiel:

git revert b2cb7c248d416409f8eb42b561cbff91b0601712

Dann wurde ich aufgefordert, das Zurücksetzen festzuschreiben (genau wie beim Ausführen von 'git commit'). Mein Standard-Terminalprogramm ist Vim, also habe ich ausgeführt:

:wq 

Schließlich habe ich die Änderung in das Repository verschoben mit:

git push
jrc16
quelle