752 Stimmen

Rückgängig machen einer Übergabe durch einen SHA-Hash in Git?

Mir ist nicht klar, wie git revert Werke. Ich möchte zum Beispiel zu einem Commit zurückkehren, der sechs Commits hinter dem Head liegt, und dabei alle Änderungen in den dazwischen liegenden Commits rückgängig machen.

Sagen Sie seine SHA Hash ist 56e05fced214c44a37759efa2dfc25a65d8ae98d . Warum kann ich dann nicht einfach etwas tun wie:

git revert 56e05fced214c44a37759efa2dfc25a65d8ae98d

1 Stimmen

Auch wenn diese Frage älter ist als die Frage, die jetzt als Duplikat markiert ist, hat diese eine bessere Antwort. meta.stackexchange.com/questions/147643/

20 Stimmen

Diese Frage und die oberste Antwort hier können Git-Benutzer verwirren. Nur zum besseren Verständnis der Terminologie: Sie brauchen nicht zurückkehren zu eine Verpflichtung. Sie können entweder zurückgesetzt auf eine Übergabe (das ist wie eine Zeitreise mit der Zeitmaschine) oder zurückkehren einen Commit (das ist so, als ob man einen Commit zurückziehen würde, als ob er nie existiert hätte - allerdings bleibt die Revert-Information in der Historie erhalten, so dass man einen Revert wieder rückgängig machen kann, wenn man das möchte) Beachten Sie auch, dass Sie nicht das m-Flag verwenden und eine Commit-Nachricht eingeben sollten, wenn Sie während des Prozesses Konflikte bekommen. Die automatische Meldung, die Git liefert, ist informativer, wenn man in der Historie zurückblickt.

1 Stimmen

@alexrogins Was bedeutet es, einen Commit zurückzuziehen, als hätte er nie existiert? Ich bin mir auch nicht sicher, was "Revert a revert" bedeutet - ich schätze den Kommentar, gute Informationen, ich suche nur nach mehr Details über Ihre Perspektive.

1361voto

CB Bailey Punkte 693084

Wenn Sie einen Commit über den aktuellen HEAD mit dem exakten Stand bei einem anderen Commit durchführen wollen und dabei alle Zwischen-Commits rückgängig machen wollen, dann können Sie reset um den korrekten Status des Indexes für die Übergabe zu erstellen.

# Reset the index and working tree to the desired tree
# Ensure you have no uncommitted changes that you want to keep
git reset --hard 56e05fced

# Move the branch pointer back to the previous HEAD
git reset --soft "HEAD@{1}"

git commit -m "Revert to 56e05fced"

90 Stimmen

Wäre es nicht gleichwertig (und um einen Befehl kürzer), dies zu tun? git reset --hard 56e05fced als ersten Befehl, und überspringen Sie dann den letzten git reset --hard ?

27 Stimmen

Als ich dies tat, hatte ich einen Haufen von Untracked Files im Arbeitsbaum. Wenn ich mir jedoch die Historie ansehe, kann ich feststellen, dass diese Dateien einen entsprechenden Lösch-Commit in diesem "Revert to SHA"-Commit haben. Also nach git reset --hard am Ende können Sie Folgendes tun git clean -f -d um alle noch nicht verfolgten Dateien zu bereinigen. Außerdem danke ich Ihnen, dass Sie mir geholfen haben, eine Krise zu lösen!

5 Stimmen

Muss ich die git reset --soft HEAD@{1} bedingungslos? Ich meine, immer mit einem Wert von 1?

189voto

Jakub Narębski Punkte 286531

Was git-revert erzeugt einen Commit, der die Änderungen eines bestimmten Commits rückgängig macht und einen Commit erzeugt, der umgekehrt (nun ja, reziprok) zu einem bestimmten Commit ist. Daher

git revert <SHA-1>

sollte funktionieren und tut es auch.

Wenn Sie zu einem bestimmten Commit zurückspulen wollen, und das können Sie, weil dieser Teil der Geschichte noch nicht veröffentlicht wurde, müssen Sie git-reset , nicht git-revert:

git reset --hard <SHA-1>

(Beachten Sie, dass --hard würde dazu führen, dass Sie alle nicht übertragenen Änderungen im Arbeitsverzeichnis verlieren).

Zusätzliche Hinweise

Übrigens, vielleicht ist es nicht offensichtlich, aber überall dort, wo in der Dokumentation steht <commit> o <commit-ish> (oder <object> ), können Sie eine SHA-1 Kennung (vollständig oder verkürzt) der Übergabe.

10 Stimmen

Falls Ihr Verlauf bereits vor dem Hard-Reset auf eine Remote übertragen wurde müssen Sie den neu zurückgesetzten Zweig mit git push -f aber Sei gewarnt dass dadurch möglicherweise unbeabsichtigt die Commits anderer Benutzer gelöscht werden könnten, und wenn nicht neue Commits gelöscht werden, dann werden andere Benutzer gezwungen, ihre Arbeit mit dem zurückgesetzten Zweig neu zu synchronisieren, Vergewissern Sie sich also vorher, dass Ihre Mitarbeiter damit einverstanden sind.

4 Stimmen

Das scheint die beste Antwort zu sein. Sie erklärt auch deutlich den Unterschied zwischen git revert und git reset.

95voto

darshit khatri Punkte 851

Der beste Weg, zu einem bestimmten Commit zurückzukehren, ist:

git reset --hard <commit-id>

Ensuite :

git push <reponame> -f

43 Stimmen

Neulinge sollten sich bewusst sein, dass push -f kann die Geschichte zerstören. Aber manchmal ist es das, was man will :)

1 Stimmen

Manchmal ist man wirklich froh, dass der Verlauf gelöscht wird... ich habe nach dieser Option -f gesucht, danke!

0 Stimmen

Danke, um genau zu sein, musste ich -> git push origin master -f eingeben, wobei <reponame> nicht einfach origin sein kann, zumindest bei mir

90voto

Er macht den besagten Commit rückgängig, d.h. er fügt ihm den entgegengesetzten Commit hinzu. Wenn Sie eine frühere Revision auschecken wollen, können Sie das tun:

git checkout 56e05fced214c44a37759efa2dfc25a65d8ae98d

1 Stimmen

Dann kann ich das einfach mit dem Kopf zusammenführen? Was ist, wenn ich tonnenweise Konflikte erwarte? Kann ich diesen Commit einfach zum Head "as-is" machen und alle Konflikte überschreiben?

1 Stimmen

Ich bin mir nicht sicher, von welchem Kopf Sie sprechen. Sie können einfach umziehen Sie Ihren Kopf zurück zu dieser Übergabe. (zum Beispiel durch Löschen und Erstellen eines Zweigs). Wenn Sie einen "Merge"-Commit in den Head machen wollen, was praktisch die Umkehrung der Zwischen-Commits ist, können Sie "Merge mit unserer" Strategie verwenden. Wählen Sie Ihre Option und lesen Sie die Manpages. Die Macht wartet nur darauf, dass Sie sie nutzen ;-)

0 Stimmen

Das macht Sinn. Der Grund, warum ich frage, ist, dass Git mir jetzt sagt, dass ich auf keinem Zweig bin.

85voto

Jacob Dam Punkte 1818

Aktualisiert:

Wenn keine Merge Commits dazwischen lagen, ist diese Antwort eine einfachere Methode: https://stackoverflow.com/a/21718540/541862

Aber wenn es einen oder mehrere Merge Commits gab, wird diese Antwort nicht funktionieren, also bleiben Sie bei dieser (die in allen Fällen funktioniert).

Ursprüngliche Antwort:

# Create a backup of master branch
git branch backup_master

# Point master to '56e05fce' and
# make working directory the same with '56e05fce'
git reset --hard 56e05fce

# Point master back to 'backup_master' and
# leave working directory the same with '56e05fce'.
git reset --soft backup_master

# Now working directory is the same '56e05fce' and
# master points to the original revision. Then we create a commit.
git commit -a -m "Revert to 56e05fce"

# Delete unused branch
git branch -d backup_master

Die beiden Befehle git reset --hard y git reset --soft sind hier magisch. Die erste ändert das Arbeitsverzeichnis, aber sie ändert auch head (den aktuellen Zweig). Wir fixieren den head durch den zweiten.

3 Stimmen

Das -a in Ihrem Commit ist nicht notwendig.

5 Stimmen

Perfekt. Dies sollte ein einziger Befehl im Git-Cli werden, IMO.

3 Stimmen

Sehr schön! Das ist viel besser als git revert 56e05fce..HEAD weil es nur eine einzige Übergabe ist

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