it-swarm.com.de

Mercurial: Wie mache ich das letzte unpushed Commit rückgängig?

Ich habe mich versehentlich zu meinem lokalen Repository verpflichtet. Um genauer zu sein, habe ich Änderungen an vielen Dateien gleichzeitig vorgenommen, wenn ich sie einzeln festschreiben wollte. 

Wie kann ich dieses Commit rückgängig machen und meine Arbeitskopie in den Zustand vor dem Commit zurückbringen, damit ich das tun kann, was ich eigentlich hätte tun sollen?

Ich habe seit dem Commit nicht mehr gestoßen oder gezogen. 


Sie können vermuten, dass es sich um ein Duplikat handelt, deshalb werde ich erklären, warum die folgenden Fragen unterschiedlich sind oder meine Frage nicht beantworten:

Mercurial letzter Commit rückgängig machen

Eine Antwort darauf gibt an, dass Sie dies mit hg commit --amend tun können, erklärt jedoch nicht wie oder gibt ein Beispiel dafür. Die Mercurail-Hilfe schreibt es mir auch nicht aus.

Wie "Rollback" zuletzt auf Mercurial begehen?

Zu verwendende Staaten hg rollback. Dieser Befehl ist anscheinend veraltet, ich habe es trotzdem versucht, aber ich habe die Meldung erhalten: Keine Rollback-Informationen verfügbar. Schade, dass dies nicht funktioniert, da dies ein wirklich intuitiver Weg ist, um das zu erreichen, was ich will.

30
crobar

Basierend auf Informationen aus dieser Frage :

hg strip --keep --rev .
--keep: do not modify working directory during strip
--rev . (der Punkt kennzeichnet den letzten Commit. Lesen Sie die Antwort von sid0 zu den Nachkommen)


Für Leute, die sich mit der Sprache von git auskennen, suchen Sie nach git reset --mixed HEAD^ 

hard was Ihre Änderungen verwerfen würde und Ihre Arbeit "verschwinden lassen" würde (ich gehe davon aus, dass dies keine Option ist) 

soft würde das Festschreiben rückgängig machen, aber zuvor festgeschriebene Dateien indizieren (dh verfolgt) 

mixed behält Ihre geänderten Dateien bei, weist den Index jedoch an, das Commit rückgängig zu machen. in git-speak: git st würde Changes not staged for commit sagen 


Siehe auch git-reset docs , Unterschied git reset soft/mixed , git/hg Äquivalenztabelle für Befehle

35
maosmurf

Ok, ich glaube, ich habe die Antwort gefunden. Sie soll die Erweiterung strip aktivieren und den folgenden Befehl verwenden:

hg strip -r -1 --keep

Dadurch wird die letzte Revision aus dem Archiv entfernt (das -r -1-Bit), und die --keep-Option bedeutet, dass keine Änderungen an der Arbeitskopie vorgenommen werden. So erhalten Sie eine Arbeitskopie, die genau vor dem Commit war, und kein letztes Commit im Repository.

Ich bin kein Mercurial-Experte, also auf eigenes Risiko.

24
crobar

Was ich in dieser Situation tun würde, ist einen neuen Zweig mit den gewünschten Änderungen zu erstellen, bevor ich daran dachte, das schlechte Änderungsset zu entfernen. In diesem Fall muss ich also zur Revision zurückkehren, bevor ich das schlechte Commit durchführe, meine Änderungen wiederholen und dann mehrere Commits machen, eines für jede Datei.

Schritt für Schritt:

1) Gehen Sie zurück zu vor dem schlechten Commit.

% cd <top of repo>
% hg log -l 5
<identify the last good revision>
% hg update -r <last good revision number>

2) Nehmen Sie die Änderungen erneut vor: Ich würde einen Patch erhalten, der die von mir gewünschten Änderungen beschreibt, und ihn auf den Baum anwenden. (Ich gehe davon aus, dass der Tipp aktuell zeigt, wo wir angefangen haben.)

% hg diff -r .:tip | patch -p1
patching file a/b/c/d
patching file a/b/e/f

3) Neue Commits machen: Wir sind jetzt wieder im Zustand, bevor Sie das Commit gemacht haben, das Sie aufteilen wollten. Machen Sie hg status und sehen Sie sich die geänderten Dateien an. Stellen Sie sicher, dass alles Ihren Erwartungen entspricht. An dieser Stelle können Sie entweder die Dateien nacheinander festschreiben, indem Sie sie in der Befehlszeile benennen, oder eine Erweiterung wie record oder crecord verwenden, um sie interaktiv auszuwählen.

% hg commit a/b/c/d
% hg commit a/b/e/f

...oder...

% hg crecord
<select files in UI>
% hg crecord
<select files in UI>

Sie erhalten ein Repo, das so aussieht:

o----o----B
      \
       \
        --o----o----o----T

Wobei B das alte schlechte Commit ist und T der neue Tipp des Repos ist. Wenn Sie diesen Zweig dann als geschlossen definieren möchten, damit er nicht in den Protokollen/etc angezeigt wird, können Sie ...

% hg update -r <revision B>
% hg commit --close_branch
% hg update -r tip

Wenn Sie es vollständig entfernen möchten, können Sie es entfernen.

% hg strip -r <revision B>

In jedem Fall sieht Ihr Protokoll so aus, als wäre nichts passiert.

1
Paul S

@ crobars Beitragsursache # der Charaktere zu kommentieren und auszuarbeiten reicht nicht aus.

wenn Sie ein lokales Commit ausführen (kein Push) und dann hg strip -r -1 --keep ausführen, wird Ihr vorheriges Commit gelöscht UND Ihre Liste der Dateien wird beibehalten, die auf das Übertragen warten. Im Grunde ist dies ein komplettes Rückgängigmachen. Wenn ich hg stripe -r -1 ohne den --keep verwende, löscht es immer noch Ihr vorheriges Commit, ABER wenn ich versuche, die zu bezeichnenden Dateien aufzulisten, kann es keine Änderung finden, daher würde ich dies nicht empfehlen.

wenn ich ein Commit mache, dann mache ich einen Push (zu Remote), dann mache hg strip -r -1 --keep, es tut genau das, was es tun soll, ABER wenn du ein anderes Commit machst, dann Push, es erzeugt einen anderen Zweig. 

I.E. 

o----o----Branch(local)
      \
       \
        --o----o----o----Branch(with previous Push)

meine Quelle/Referenz: Testen dieser Szenarien