Rollback zu einem alten Git-Commit in einem öffentlichen Repo

802

Wie kann ich zu einem bestimmten Commit in Git zurückkehren ?

Die beste Antwort, die mir jemand geben konnte, war, git revertX-mal zu verwenden, bis ich das gewünschte Commit erreicht habe.

Nehmen wir also an, ich möchte zu einem Commit zurückkehren, das 20 Commits alt ist. Ich müsste es 20 Mal ausführen.

Gibt es einen einfacheren Weg, dies zu tun?

Ich kann Reset nicht verwenden, da dieses Repository öffentlich ist.

David
quelle
1
git revert <commit> funktioniert nicht?
Miku
8
Wie in meiner Frage angegeben, hilft mir das wirklich nicht, wenn ich zu etwas zurückkehren möchte, das vor 20 Commits erstellt wurde.
David
7
Diese Frage wurde hier ziemlich gut beantwortet stackoverflow.com/questions/4114095/…
user7610
4
Es ist nicht klar, was Sie unter "Zurückrollen" verstehen. Bedeutet das, dass Sie Ihre Arbeitskopie vorübergehend auf eine bestimmte Revision umstellen möchten? Oder möchten Sie den Verlauf Ihres Repositorys dauerhaft auf eine bestimmte Revision zurücksetzen?
1
Sie sollten eine Antwort akzeptieren und möglicherweise alle anderen Antworten, die Sie mögen, abstimmen.
Nabil Kadimi

Antworten:

1194

Versuche dies:

git checkout [revision] .

Wo [revision]ist der Commit-Hash (zum Beispiel :) 12345678901234567890123456789012345678ab.

Vergiss das .am Ende nicht, sehr wichtig. Dadurch werden Änderungen auf den gesamten Baum angewendet. Sie sollten diesen Befehl im Git-Projektstamm ausführen. Wenn Sie sich in einem Unterverzeichnis befinden, ändert dieser Befehl nur die Dateien im aktuellen Verzeichnis. Dann verpflichten Sie sich und Sie sollten gut sein.

Sie können dies rückgängig machen, indem Sie

git reset --hard 

Dadurch werden alle Änderungen aus dem Arbeitsverzeichnis und dem Staging-Bereich gelöscht.

Alex Reisner
quelle
7
@AlexReisner Dieser Zeitraum an den Endpunkten des Verzeichnisses, in dem Sie sich gerade befinden, ist nicht unbedingt das gesamte Git-Projekt, richtig? Wenn Sie die Änderungen auf das gesamte Projekt anwenden möchten, würden Sie stattdessen ': /' wie in 'git add: /' verwenden, wenn Sie sich derzeit nicht im Stammverzeichnis des Git-Projekts befinden?
MSpreij
10
Hinweis: Wenn Sie Ihrem Projekt seitdem neue Dateien hinzugefügt haben, werden diese nicht gelöscht. Wenn Sie also zum Erstellen gehen (abhängig von Ihrer Plattform), können immer noch Fehler auftreten. Löschen Sie die neuen Dateien und los geht's.
TheWestIsThe ...
6
@MSpreij Sie sollten diesen Befehl im Git-Projektstamm ausführen. Wenn Sie sich in einem Unterverzeichnis befinden, ändert dieser Befehl nur die Dateien im aktuellen Verzeichnis.
volatilevar
3
Es ist großartig, wenn Sie ein Projekt in ein anderes Verzeichnis klonen und git checkout [Revision] verwenden können. um zu einer bestimmten Revision zurückzukehren und sie dann mit demselben Projekt in einem anderen Verzeichnis zu vergleichen. Spart viel Zeit.
Donato
4
Verdammt, ich habe das "." Vergessen. Welchen Schaden habe ich meinem Repository zugefügt?
Eule
196

So führen Sie ein Rollback auf ein bestimmtes Commit durch:

git reset --hard commit_sha

So rollen Sie 10 Commits zurück:

git reset --hard HEAD~10

Sie können "git revert" wie im folgenden Beitrag verwenden, wenn Sie den Verlauf nicht neu schreiben möchten

Wie kann ich das Git-Repository auf ein vorheriges Commit zurücksetzen?

Naga Kiran
quelle
4
einziger Unterschied zwischen diesem Ansatz und "Git Checkout [Revision]". ist, dass letztere Revisionen beibehält.
Deeshank
53
Diese Antwort ist FALSCH, da OP ausdrücklich angibt "Ich kann Reset nicht verwenden, da dieses Repo öffentlich ist"
Yarin
4
Wenn Repo öffentlich ist, gibt es meines Erachtens keine Möglichkeit, das Commit für das öffentliche Repository ohne Force Push (git push -f) zurückzusetzen, da dies Auswirkungen auf die Personen hat, die die Änderungen vor dem Rollback vorgenommen haben. Das Zurücksetzen kann also auch in der lokalen Sandbox eines öffentlichen Repos verwendet werden.
Naga Kiran
4
Es ist großartig, dass dies einen abgetrennten KOPF vermeidet! Genau das, wonach ich gesucht habe.
Cyber-Mönch
1
In meinem Fall hat dies funktioniert. Verwenden Sie dann "Git Pull", um schnell zum Kopf vorzuspulen, nachdem Sie Regressionen usw. Getestet haben.
Peter Quiring
86

Nun, ich denke die Frage ist, was meinst du mit "Rollback"? Wenn Sie dies nicht können, resetweil es öffentlich ist und Sie den Commit-Verlauf beibehalten möchten, möchten Sie dann nur, dass Ihre Arbeitskopie ein bestimmtes Commit widerspiegelt? Verwenden Sie git checkoutund den Commit-Hash.

Bearbeiten: Wie in den Kommentaren erwähnt, werden git checkoutSie bei Verwendung ohne Angabe eines Zweigs in den Status "Kein Zweig" versetzt. Verwenden Sie git checkout <commit> -b <branchname>diese Option, um in einen Zweig oder git checkout <commit> .in den aktuellen Zweig auszuchecken.

Ben
quelle
Versetzt Sie dies nicht in den seltsamen Zustand "Derzeit nicht in einem Zweig"? Wie übernehmen Sie Änderungen, um den Rollback abzuschließen?
Alex Reisner
Nun, ich schlage nur die Verwendung von vor git checkout- er kann in jede Filiale (aktuell oder neu) einchecken, die er wünscht. Ich werde meine Antwort aktualisieren, damit sie nicht mehrdeutig ist.
Ben
2
Ich habe es versucht, aber ich denke nicht, dass dies der richtige Weg ist, da es stagnierende Dateien hinterlässt. Dadurch werden keine Dateien gelöscht, die nicht in diesem letzten Commit enthalten waren.
David
3
Wenn Sie sich in einem Arbeitsverzeichnis befinden und im Master bleiben, müssen Sie git resetdiese Dateien löschen, was Sie nicht möchten. Versuchen Sie es in einem separaten Zweig: git checkout <commit> -b <branchname>Sie werden keine stagnierenden Dateien in diesem Zweig haben .
Ben
2
Das Problem bei der Verwendung checkoutist, dass keine Dateien gelöscht werden, die in einem vorherigen Commit hinzugefügt wurden.
42

Das Originalplakat besagt:

Die beste Antwort, die mir jemand geben konnte, war, git revertX-mal zu verwenden, bis ich das gewünschte Commit erreicht habe.

Nehmen wir also an, ich möchte zu einem Commit zurückkehren, das 20 Commits alt ist. Ich müsste es 20 Mal ausführen.

Gibt es einen einfacheren Weg, dies zu tun?

Ich kann Reset nicht verwenden, da dieses Repo öffentlich ist.

Es ist nicht notwendig, git revertX-mal zu verwenden. git revertkann einen Festschreibungsbereich als Argument akzeptieren, sodass Sie ihn nur einmal verwenden müssen, um einen Bereich von Festschreibungen zurückzusetzen. Wenn Sie beispielsweise die letzten 20 Commits zurücksetzen möchten:

git revert --no-edit HEAD~20..

Die Commit Bereich HEAD~20..kurz ist für HEAD~20..HEADund Mittel „starten vom 20 - ten Elternteil des HEAD begehen, und kehrt alle Commits , nachdem es auf HEAD up“.

Dadurch werden die letzten 20 Commits zurückgesetzt, vorausgesetzt, es handelt sich bei keinem dieser Commits um Merge-Commits. Wenn es Merge-Commits gibt, können Sie nicht alle in einem Befehl zurücksetzen. Sie müssen sie einzeln mit zurücksetzen

git revert -m 1 <merge-commit>

Beachten Sie auch, dass ich mit einem Bereich mit git revertGit Version 1.9.0 getestet habe. Wenn Sie eine ältere Version von git verwenden, git revertfunktioniert die Verwendung eines Bereichs mit möglicherweise oder möglicherweise nicht.

In diesem Fall git revertwird gegenüber bevorzugt git checkout.

Beachten Sie, dass im Gegensatz zu dieser Antwort, die besagt, dass verwendet werden sollgit checkout , git revert tatsächlich alle Dateien entfernt werden, die in einem der Commits hinzugefügt wurden, die Sie zurücksetzen . Dies ist die richtige Methode, um eine Reihe von Revisionen zurückzusetzen.

Dokumentation

Railgun
quelle
Hinweis : Dadurch wird ein neues Commit mit den zurückgesetzten Änderungen erstellt. Perfekt für die Frage von OP. Aber stellen Sie sicher, dass Sie das wollen. (Die Beispiele im oben verlinkten git-revert- Dokument sind ausgezeichnet.) Wenn Sie stattdessen frühere Commits untersuchen möchten (dh bevor Sie auswählen, auf welches Commit zurückgesetzt werden soll), verwenden Sie die in anderen Antworten erwähnte Checkout-Option, wobei Sie die Kommentare anderer berücksichtigen über gelöschte Dateien gemacht.
SherylHohman
@SherylHohman Beim Zurücksetzen auf ein vorheriges Commit wird kein neues Commit erstellt. Ich kann mir nicht vorstellen, was du hier meinst.
27

Schritt 1: Liste der Commits abrufen:

git log

Sie erhalten eine Liste wie in diesem Beispiel:

[Comp:Folder User$ git log
commit 54b11d42e12dc6e9f070a8b5095a4492216d5320
Author: author <[email protected]>
Date:   Fri Jul 8 23:42:22 2016 +0300

This is last commit message

commit fd6cb176297acca4dbc69d15d6b7f78a2463482f
Author: author <[email protected]>
Date:   Fri Jun 24 20:20:24 2016 +0300

This is previous commit message

commit ab0de062136da650ffc27cfb57febac8efb84b8d
Author: author <[email protected]>
Date:   Thu Jun 23 00:41:55 2016 +0300

This is previous previous commit message
...

Schritt 2: Kopieren Sie den erforderlichen Commit-Hash und fügen Sie ihn zum Auschecken ein:

git checkout fd6cb176297acca4dbc69d15d6b7f78a2463482f

Das ist alles.

Igor
quelle
11
git read-tree -um @ $commit_to_revert_to

werde es tun. Es ist "Git Checkout", aber ohne HEAD zu aktualisieren.

Sie können den gleichen Effekt mit erzielen

git checkout $commit_to_revert_to
git reset --soft @{1}

Wenn Sie es vorziehen, Komfortbefehle miteinander zu verbinden.

Diese lassen Sie mit Ihrem Arbeitsbaum und Index im gewünschten Zustand, Sie können nur git commitzum Abschluss.

jthill
quelle
Dies ist der einzige einfache Ansatz, der wie ein Zauber funktioniert hat! Ich habe von head ausgecheckt, diesen Befehl ausgeführt und die hinzugefügten Dateien, die wir eingeführt hatten, erfolgreich entfernt und alle Änderungen rückgängig gemacht. Ausgezeichnet.
Kamranicus
6

Willst du HEAD Detached Mode?

Wenn Sie die X-Zeit mit einem DETACHED HEAD auf ein bestimmtes Commit zurücksetzen möchten (was bedeutet, dass Sie nichts durcheinander bringen können), verwenden Sie auf jeden Fall Folgendes:

(Ersetzen Sie X durch die Anzahl der Commits, die Sie zurückgehen möchten.)

git checkout HEAD~X

IE, um ein Commit zurück zu gehen:

git checkout HEAD~1
Karl Morrison
quelle
1
Ich würde den Teil mit ... schwer zu glauben ... entfernen. Es scheint persönlich zu sein, und auch jemand hat es in einem Kommentar oben erwähnt, und auch in @ken in seiner Antwort.
MeJustAndrew
@meJustAndrew Es ist, so viele Antworten auf SO, die die Leute nur verwirren, es ist ziemlich nervig.
Karl Morrison
Was für eine einfache und direkte Antwort.
Ammad
2

Angenommen, Sie arbeiten an einem Projekt und nach einem Tag oder so. Sie bemerken, dass eine Funktion immer noch Fehler liefert. Sie wissen jedoch nicht, welche Änderung Sie vorgenommen haben, die den Fehler verursacht hat. Sie müssen also frühere Arbeitseinsätze fischen. So kehren Sie zu einem bestimmten Commit zurück:

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 .

Ok, das Commit funktioniert also für Sie. Kein Fehler mehr. Sie haben das Problem festgestellt. Jetzt können Sie zum letzten Commit zurückkehren:

git checkout 792d9294f652d753514dc2033a04d742decb82a5 .

Und checken Sie eine bestimmte Datei aus, bevor sie den Fehler verursacht hat (in meinem Fall verwende ich das Beispiel Gemfile.lock):

git checkout 8a0fe5191b7dfc6a81833bfb61220d7204e6b0a9 -- /projects/myproject/Gemfile.lock

Auf diese Weise können Sie Fehler behandeln, die Sie in Commits erstellt haben, ohne die Fehler erst später zu bemerken.

Donato
quelle
2

Die Commit-ID für jedes Commit finden Sie im Abschnitt Commits von GitHub / BitBucket / Gitlab. Angenommen, Ihre Festschreibungs- ID lautet 5889575. Wenn Sie zu diesem Teil in Ihrem Code zurückkehren möchten, müssen Sie lediglich Folgendes eingeben

git checkout 5889575 .

Dies bringt Sie zu diesem Zeitpunkt in Ihrem Code.

Naved Ahmad
quelle
1

Ich bin nicht sicher, was sich geändert hat, aber ich kann ein bestimmtes Commit ohne diese Option nicht auschecken --detach. Der vollständige Befehl, der für mich funktionierte, war: git checkout --detach [commit hash]

Um aus dem getrennten Zustand zurückzukehren, musste ich meine lokale Niederlassung auschecken: git checkout master

Ken
quelle
Das Auschecken masterbehebt das Problem, während der Arbeit getrennt zu bleiben git reset --hardoder git checkout -- .zu arbeiten, aber getrennt zu
bleiben
0

Hier ist ein Beispiel dafür

    cd /yourprojects/project-acme 


    git checkout efc11170c78 .
mcvkr
quelle