Gibt es eine Möglichkeit, lokale Commits in Mercurial zu löschen?

209

Also mache ich immer wieder einen dummen Fehler in Mercurial. Oft beginne ich mit der Arbeit, ohne ein "hg pull" und ein "hg update" durchzuführen. Wenn ich versuche, meine Änderungen zu übertragen, wird eine Fehlermeldung angezeigt.

Gibt es eine Möglichkeit, meine lokalen Commits zu löschen, damit ich nicht mehrere Köpfe, Zweige usw. erstellen kann? Ich möchte nur meine lokalen Commits löschen, meine Änderungen mit dem Tipp zusammenführen und dann erneut festschreiben. Klingt einfach, oder? Ich kann anscheinend keine Möglichkeit finden, lokale Commits einfach zu löschen, damit ich sie sauber mit dem Tipp zusammenführen kann.

Wieder versuche ich nur lokale Commits zu löschen, die mit "hg ci" gemacht wurden. Ich möchte keine Dateien ändern, zurücksetzen usw.

user191535
quelle
Mögliches Duplikat stackoverflow.com/questions/2139165/…
N 1.1
12
Es ist kein dummer Fehler, es ist ein normaler Workflow, wenn mehrere Personen gleichzeitig mit demselben Repository arbeiten.
Juozas Kontvainis

Antworten:

247

Aktivieren Sie die Erweiterung " Streifen " und geben Sie Folgendes ein:

hg strip #changeset# --keep

Wo #changeset#ist der Hash für das Änderungsset, das Sie entfernen möchten? Dadurch wird der Änderungssatz einschließlich der von ihm abgeleiteten Änderungssätze entfernt und Ihr Arbeitsverzeichnis bleibt unberührt . Wenn Sie auch Ihre festgeschriebenen Codeänderungen rückgängig machen möchten, entfernen Sie die --keepOption.

Weitere Informationen finden Sie in der Streifenerweiterung .

Wenn Sie den "unbekannten Befehl 'strip'" erhalten, müssen Sie ihn möglicherweise aktivieren. Suchen Sie dazu die Datei .hgrcoder Mercurial.iniund fügen Sie Folgendes hinzu:

[extensions]
strip =

Beachten Sie, dass (wie Juozas in seinem Kommentar erwähnt hat) das Vorhandensein mehrerer Köpfe in Mercurial ein normaler Workflow ist. Sie sollten den Befehl strip nicht verwenden, um das zu bekämpfen. Stattdessen sollten Sie Ihren Kopf mit dem eingehenden Kopf zusammenführen, Konflikte lösen, testen und dann pushen.

Der stripBefehl ist nützlich, wenn Sie Änderungssätze, die den Zweig verschmutzen, wirklich entfernen möchten. Wenn Sie sich in der Situation dieser Frage befinden und alle "Entwurfs" -Änderungssätze dauerhaft vollständig entfernen möchten , lesen Sie die Top-Antwort , die im Grunde Folgendes empfiehlt:

hg strip 'roots(outgoing())'
Samaursa
quelle
8
@ Bharath: Sie müssen die Erweiterung
aktivieren
1
Seit Mercurial 2.8 ist Strip eine eigenständige Erweiterung, also strip = in Ordnung. WhatsNew für Mercurial 2.8
Chih-Hsuan Yen
104

Wenn Sie Hg Tortoise verwenden, aktivieren Sie einfach die Erweiterung " Strip " in:

  1. Datei / Einstellungen / Erweiterungen /
  2. Streifen auswählen

right clickWählen Sie dann die untere Revision aus, von der aus Sie mit dem Striping beginnen möchten, indem Sie darauf klicken und Folgendes auswählen:

  1. Verlauf ändern
  2. Streifen

Genau wie dieser:

Geben Sie hier die Bildbeschreibung ein

In diesem Beispiel wird es von der 19. bis zur letzten festgeschriebenen Revision gelöscht (22).

EliuX
quelle
2
File/Settings/Extensions/Ich wünschte, ich könnte mehr Stimmen hinzufügen. Vielen Dank!
Dyatchenko
Argh! Ich habe es versucht, aber es schien alle meine Änderungen zu sichern, obwohl ich nicht "keine Sicherung" oder "lokale Änderungen verwerfen" abgehakt habe. Ich wollte diese Änderungen behalten, nur nicht festschreiben! Gibt es eine Möglichkeit, sie jetzt wiederherzustellen?
Tim Tisdall
2
Ich kann anscheinend keinen Weg finden, es richtig zu machen, aber es scheint, als würde ich den Inhalt behalten, den Sie weitergeben müssen, --keepund TortoiseHg bietet diese Option nicht an. Also ... müssen Sie es an der Kommandozeile mit tun hg strip -r . --keep.
Tim Tisdall
3
aus der Strip-Hilfe: 'Alle gestrippten Änderungssätze werden in ".hg / strip-backup" als Bundle gespeichert (siehe "hg help bundle" und "hg help entbündeln"). Sie können wiederhergestellt werden, indem "hg unbundle .hg / strip-backup / BUNDLE" ausgeführt wird, wobei BUNDLE die vom Strip erstellte Bundle-Datei ist.
Tim Tisdall
Im SourceTree war es auch nützlich. Vielen Dank!
Ponomarenko Oleh
22

Moderne Antwort (nur relevant nach Mercurial 2.1):

Verwenden Sie Phasen und markieren Sie die Revision (en), die Sie nicht freigeben möchten, als geheim (privat). Auf diese Weise werden sie beim Senden nicht gesendet.

In TortoiseHG können Sie mit der rechten Maustaste auf ein Commit klicken, um dessen Phase zu ändern.

Außerdem: Sie können die Erweiterung "rebase" auch verwenden, um Ihre lokalen Commits nach dem Abrufen an den Kopf des freigegebenen Repositorys zu verschieben.

Tom Leys
quelle
Privat == Geheimnis jetzt
Dmitry Osinovskiy
15

Wie alle anderen darauf hinweisen, sollten Sie wahrscheinlich nur die Köpfe ziehen und dann zusammenführen. Wenn Sie Ihre Commits jedoch wirklich ohne eines der EditingHistory- Tools loswerden möchten, können Sie nur hg clone -rIhr Repo verwenden, um alle Änderungen außer diesen zu erhalten.

Dadurch werden sie nicht aus dem ursprünglichen Repository gelöscht, es wird jedoch ein neuer Klon erstellt, der sie nicht enthält. Dann können Sie das von Ihnen geänderte Repo löschen (wenn Sie möchten).

Ry4an Brase
quelle
Löscht "hg clone -r" lokale Änderungen? Ich möchte nur lokale Commits löschen, um die Dinge einfach zu halten.
user191535
4
Sie werden nicht aus dem geklonten Repository gelöscht, es wird jedoch ein neuer Klon erstellt, der sie nicht enthält. Anschließend können Sie das von Ihnen geänderte Repo löschen, wenn Sie möchten.
Ry4an Brase
9

Ich bin auch auf dieses Problem gestoßen. Ich habe 2 gemacht commitund wollte beide Commits zurücksetzen und löschen.

$ hg rollback

Aber hg rollbackrollt einfach zurück zum letzten Commit, nicht zu den 2 Commits. Zu diesem Zeitpunkt habe ich das nicht bemerkt und den Code geändert.

Als ich herausfand, hg rollbackdass gerade ein Commit zurückgesetzt wurde, stellte ich fest, dass ich es verwenden konnte hg strip #changeset#. Also habe ich hg log -l 10die letzten 10 Commits gefunden und das richtige Änderungsset erhalten, das ich wollte strip.

$ hg log -l 10
changeset:   2499:81a7a8f7a5cd
branch:      component_engine
tag:         tip
user:        myname<[email protected]>
date:        Fri Aug 14 12:22:02 2015 +0800
summary:     get runs from sandbox

changeset:   2498:9e3e1de76127
branch:      component_engine
user:        other_user_name<[email protected]>
date:        Mon Aug 03 09:50:18 2015 +0800
summary:     Set current destination to a copy incoming exchange

......

$ hg strip 2499
abort: local changes found

Was heißt abort: local changes founddas Dies bedeutet, dass hgÄnderungen am Code gefunden wurden, die noch nicht festgeschrieben wurden. Um dies zu lösen, sollten Sie hg diffden Code speichern, den Sie geändert haben, und hg revertund hg strip #changeset#. Genau wie dieser:

$ hg diff > /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
$ hg revert file_you_have_changed
$ hg strip #changeset#

Nachdem Sie die oben genannten patchSchritte ausgeführt haben, können Sie die Diff-Datei und Ihren Code wieder zu Ihrem Projekt hinzufügen.

$ patch -p1 < /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
Ich gehe meinen Weg
quelle
9

Mit der Rebase-Erweiterung können Sie dies noch einfacher umgehen. Verwenden hg pull --rebaseSie sie einfach, und Ihre Commits werden automatisch wieder in die gezogene Revision übernommen, um das Verzweigungsproblem zu vermeiden.

zu viel php
quelle
1
Auf Kosten einer ungenauen Historie und möglicher Korruption, wenn Sie etwas falsch machen.
Ry4an Brase
5

Wenn Sie mit git vertraut sind, verwenden Sie gerne histedit , das wie folgt funktioniert git rebase -i.

Neo
quelle
4

hg stripist was Sie suchen. Es ist analog, git resetwenn Sie mit Git vertraut sind.

Konsole verwenden:

  1. Sie müssen die Revisionsnummer kennen. hg log -l 10. Dieser Befehl zeigt die letzten 10 Commits an. Finden Sie das Commit, das Sie suchen. Sie benötigen eine 4-stellige Nummer aus der Änderungssatzzeilechangeset: 5888:ba6205914681

  2. Dann hg strip -r 5888 --keep. Dadurch wird der Datensatz des Commits entfernt, aber alle Dateien bleiben geändert, und Sie können sie erneut festschreiben. (Wenn Sie Dateien löschen möchten, um nur --keep zu entfernenhg strip -r 5888

val.sytch
quelle
1

[Hg Tortoise 4.6.1] Wenn es sich um eine kürzlich durchgeführte Aktion handelt, können Sie die Aktion "Rollback / Rückgängig" verwenden (Strg + U).

HG Schildkrötenbild

Tomas
quelle
Überprüfen Sie die Aufnahme eines Bildes.
Bill Keller
0

Zusätzlich zu Samaursas hervorragender Antwort können Sie die evolveErweiterung pruneals sichere und wiederherstellbare Version verwenden strip, mit der Sie zurückkehren können, falls Sie etwas falsch machen.

Ich habe diesen Alias ​​auf meinem .hgrc:

 # Prunes all draft changesets on the current repository
 reset-tree = prune -r "outgoing() and not obsolete()"
 # *STRIPS* all draft changesets on current repository. This deletes history.
 force-reset-tree = strip 'roots(outgoing())'

Beachten Sie, dass pruneauch hat --keep, genau wie stripzu halten , das Arbeitsverzeichnis intakt so dass Sie die Dateien zu verpflichten .

Euller Borges
quelle