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?
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:
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
:]
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:
(von http://Mercurial-scm.org/wiki/RebaseExtension#Collapsing )
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.
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.
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 vonhg histedit
).Die automatische Umschreibelogik von
hg absorb
wird durch Verfolgen der Zeilenhistorie implementiert: Dies unterscheidet sich grundlegend von der Vorgehensweise vonhg histedit
odergit 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 vonhg histedit
odergit rebase -i
durchgeführte Zusammenführung fehlschlagen würde.
Nehmen wir an, Sie möchten die 2 letzten Commits quetschen (vereinigen).
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
Soft Reset-Zweig
hg strip --keep -r 155
Änderungen erneut vornehmen
hg commit -m "new commit message"
strip
setzt voraus, dass eine integrierte Erweiterung aktiviert ist. ~/.hgrc
config-Datei mit folgendem Inhalt erstellen/bearbeiten:
[extensions]
strip =
Ich benutze:
hg phase --draft --force -r 267
...
hg rebase --dest 282 --source 267 --collapse
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 =