it-swarm.com.de

Kann ich Commits in Mercurial besiegen?

Ich habe ein paar Verpflichtungen, die eigentlich nur eine sein sollten. Wenn ich git benutze, würde ich verwenden:

git rebase -i <some-commit-before>

und dann zerquetschen.

Kann ich das in mercurial machen? Wenn das so ist, wie?

99

Ja, dies ist mit Mercurial ohne Erweiterungen möglich, indem Sie Changesets verketten.

Wenn Sie eine Erweiterung verwenden möchten, können Sie alternativ Folgendes verwenden:

85
Ry4an Brase

Mein Favorit ist hg strip --keep Befehl. Und dann mache ich alle Änderungen in einem Commit.

Dies ist der schnellste und bequemste Weg für mich, weil ich bei meiner täglichen Arbeit gerne viele kleine Verpflichtungen eingehen möchte;)


Hinweis 1: Für strip muss eine integrierte Erweiterung mq aktiviert sein.
Hinweis 2: Mein bevorzugter Git/Mercurial-Client (SmartGit/Hg) hängt standardmäßig --keep-Parameter während strip an. Und was noch bequemer ist: Es bietet die Option join commits:]

38
G. Demecki

Die Rebase-Erweiterung funktionierte wie ein Zauber. Um Squash 2 zu begehen, gilt Folgendes:

$ hg rebase --dest .~2 --base . --collapse

Punkt ist eine Abkürzung für die aktuelle Revision.

Es ist sogar noch einfacher, wenn Sie ein paar Commits für einen Zweig haben und sie alle zu einem zusammenfassen möchten:

$ hg rebase --dest {destination branch (e.g. master)} --base . --collapse

Wie das funktioniert:

enter image description here

(von http://Mercurial-scm.org/wiki/RebaseExtension#Collapsing )

28
Martin Konicek

Wenn Sie diese Antwort lesen, können Sie jede andere Option vergessen in dieser Antwort erwähnt und verwenden Sie den Befehl fold von der evolve Erweiterung .

evolve ist eine Erweiterung von Mercurial, die uns dabei hilft, eine sichere veränderliche Geschichte zu haben, sie ist jedoch immer noch experimentell. Sie können es verwenden, indem Sie es aus seinem repo klonen und es so in Ihrem .hgrc hinzufügen.

[extensions]
evolve = ~/evolve/hgext/evolve.py

Angenommen, Sie haben geklontes Repo in Ihrem Home-Verzeichnis entwickelt. Jetzt bist du gut zu gehen. Sie können auch nach Hilfe von hg help fold suchen.

FALTBEFEHL

Sie sagen fold, eine lineare Commit-Kette zu quetschen/zu falten, die nicht gebrochen ist. Was fold tut, erstellt ein neues Changeset, das Änderungen aus allen Changesets enthält, und markiert alle diese Commits als obsolet. Bei docs können Sie dies näher betrachten.

Nehmen wir an, Sie haben die folgende Geschichte.

a -> b -> c -> d -> e -> f -> g

Sie möchten e, f und g zerdrücken. Du kannst tun

hg up g
hg fold -r e

Das Ergebnis wird sein

a -> b -> c -> d -> h

dabei ist h das Changeset, das die Änderungen aller drei Commits e, f und g enthält.

Sie können Changesets auch in der Mitte der Historie falten, d. H. Sie müssen nicht unbedingt eine Kette auswählen, die die Spitze enthält. Angenommen, Sie möchten b, c und d falten. Du kannst tun

hg up d
hg fold -r b
hg evolve --all

Dies führt zu

a -> i -> j

wobei i die gefaltete Änderungsmenge von b ist, c, d und j dieselbe Änderungsmenge wie h. Evolve-Benutzerhandbuch muss gelesen werden.

9
Pulkit Goyal

Mit Mercurial 4.8 (November 2018, 9 Jahre später) konnten Sie den neuen Befehl hg aborb in Betracht ziehen (es war eine experimentelle Funktion vor ).

Siehe " Commit-Änderungen in Mercurial 4.8 absorbieren ".

Die Absorptionserweiterung nimmt jede Änderung in Ihrem Arbeitsverzeichnis vor, ermittelt, welche Commits in Ihrer Serie diese Zeile geändert haben, und ändert die Änderung automatisch in diesen Commit.
Wenn Unklarheiten bestehen (d. H. Wenn mehrere Commits in derselben Zeile geändert wurden), ignoriert absorb diese Änderung einfach und belässt sie in Ihrem Arbeitsverzeichnis, um sie manuell aufzulösen.

Auf technischer Ebene findet hg absorb alle nicht festgeschriebenen Änderungen und versucht, jede geänderte Zeile einer eindeutigen vorherigen Festschreibung zuzuordnen.
Für jede Änderung, die sauber zugeordnet werden kann, werden die nicht festgeschriebenen Änderungen in das entsprechende vorherige Festschreiben übernommen. Von der Operation betroffene Commits werden automatisch umbasiert.
Wenn eine Änderung keiner eindeutigen vorherigen Festschreibung zugeordnet werden kann, wird sie nicht festgeschrieben, und Benutzer können auf einen vorhandenen Workflow zurückgreifen (z. B. mithilfe von hg histedit).

Die automatische Umschreibelogik von hg absorb wird durch Verfolgen der Zeilenhistorie implementiert: Dies unterscheidet sich grundlegend von der Vorgehensweise von hg histedit oder git rebase, die sich in der Regel auf Zusammenführungsstrategien stützen, die auf der 3-Wege-Zusammenführung basieren, um eine neue abzuleiten Version einer Datei mit mehreren Eingabeversionen.

Dieser Ansatz kombiniert mit der Tatsache, dass hg absorb Änderungen mit einem mehrdeutigen Anwendungs-Commit überspringt, bedeutet, dass hg absorb niemals auf Zusammenführungskonflikte stößt!

Wenn Sie Zeilen mit mehrdeutigen Anwendungszielen ignorieren, wird der Patch möglicherweise immer sauber angewendet, wenn Sie eine klassische 3-Wege-Zusammenführung verwenden. Diese Aussage klingt logisch richtig. Dies ist jedoch nicht der Fall: hg absorb kann Zusammenführungskonflikte vermeiden, wenn die von hg histedit oder git rebase -i durchgeführte Zusammenführung fehlschlagen würde.

1
VonC

Nehmen wir an, Sie möchten die 2 letzten Commits quetschen (vereinigen).

  1. Suchen Sie eine Versionsnummer

    hg log -G -l 3
    

    mögliche Ausgabe:

    @  changeset:   156:a922d923cf6f
    |  branch:      default
    |  tag:         tip
    |  user:        naXa!
    |  date:        Thu Dec 13 15:45:58 2018 +0300
    |  summary:     commit message 3
    |
    o  changeset:   155:5feb73422486
    |  branch:      default
    |  user:        naXa!
    |  date:        Thu Dec 13 15:22:15 2018 +0300
    |  summary:     commit message 2
    |
    o  changeset:   154:2e490482bd75
    |  branch:      default
    ~  user:        naXa!
       date:        Thu Dec 13 03:28:27 2018 +0300
       summary:     commit message 1
    
  2. Soft Reset-Zweig

    hg strip --keep -r 155
    
  3. Änderungen erneut vornehmen

    hg commit -m "new commit message"
    

Anmerkungen

strip setzt voraus, dass eine integrierte Erweiterung aktiviert ist. ~/.hgrc config-Datei mit folgendem Inhalt erstellen/bearbeiten:

[extensions]
strip = 
1
naXa

Ich benutze:

hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
0
sasha-ch

Ich denke, chistedit (seit Mercurial 2.3 eingebaut) ist rebase -i am nächsten, der reiner Mercurial ist (chistedit ist die interaktive Version von histedit). Sobald sich histedit im Befehl fold befindet, werden die Befehle squash von rebase und roll von rebase auf fixup von rebase abgebildet. Weitere Informationen finden Sie unter histedit docs.

Hier ist ein einfaches Beispiel. Angenommen, Sie haben Folgendes und möchten alle Änderungen von 1e21c4b1 in die vorherige Version verschieben und nur die Nachricht der vorherigen Version beibehalten. 

@  1e21c4b1 drees tip
|  A commit you want to squash
o  b4a738a4 drees
|  A commit
o  788aa028 drees
|  Older stuff

Sie können hg chistedit -r b4a738a4 ausführen, um den Verlauf zurück nach b4a738a4 zu bearbeiten. In chistedit bewegen Sie sich dann zu 1e21c4b1 und drücken Sie r, um anzuzeigen, dass Sie diese Revision rollen möchten. Beachten Sie, dass die Reihenfolge in histedit (älteste bis neueste) von hg log (neueste bis älteste) umgekehrt wird.

#0  pick   160:b4a738a49916   A commit
#1  ^roll  161:1e21c4b1500c

Nachdem Sie Ihre Änderungen ausgewählt haben, wählen Sie c, um die Änderungen zu übernehmen. Das Ergebnis ist folgendes:

@ bfa4a3be drees tip | Ein Commit O 788aa028 drees | Älteres Zeug

Wenn Sie relativ neu sind, kann histedit die bessere Wahl sein als chistedit, da die Befehlsbeschreibungen in der histedit-Datei als Referenz bereitgestellt werden. Es ist nur ein wenig mehr Bearbeitung nötig, um die Befehle mit normaler Textbearbeitung zu setzen (genau wie beim normalen Rebase).

Um entweder histedit oder chistedit zu verwenden, müssen Sie histedit zu Ihren Erweiterungen in Ihrem ~/.hgrc hinzufügen:

[extensions]
histedit =

Ich schlug chistedit vor, da es am nächsten an rebase -i liegt und überall im Verlauf funktioniert. Wenn Sie wirklich nur die aktuelle Version subsumieren wollen, dann @G. Demeckis strip-Vorschlag kann gut sein, da klar ist, was passiert. Es ist seit Mercuria 2.8 eingebaut. Um die gleichen Ergebnisse wie oben zu erhalten, können Sie Folgendes tun:

hg strip .
hg add
hg commit --amend

Hinweis strip muss wie histedit in Ihrem ~/.hgrc aktiviert sein:

[extensions]
strip =
0
studgeek