Tricks fürs Debuggen
posted by Friedrich Kastner-Masilko on April 23, 2010
Falls Sie einmal hg help --debug verwendet haben sind Ihnen vielleicht die
mit ‘debug’ beginnenden Befehle bekannt. Die meisten davon dienen zum prüfen
des internen Speichers von Mercurial, aber einige können in gewissen
Situationen sehr praktisch sein. Zwei dieser Befehle sind hg debugsetparents
und hg debugrebuildstate.
Der erste Befehl zwingt Mercurial die “richtige” Elternrevision des Arbeitsverzeichnisses zu vergessen und stattdessen die spezifizierte Revision von ‘debugsetparents’ zu nutzen. Der zweite Befehl zwingt Mercurial seinen internen Status neu zu berechnen.
Wie kann dies nun in Alltagssituationen helfen? Hier sind 3 Szenarios wo diese Befehle hilfreich sein können:
1. Verzögertes verbinden der Arbeitskopie mit dem Repository.
Stellen Sie sich ein interessantes Projekt vor, das mit Mercurial gehosted wird. Zu Beginn laden Sie nur einen Snapshot des Projekts herunter, schauen sich den Code an und spielen ein wenig herum. Sie haben das Repository nicht ganz geklont da Sie den Overhead fürs anschauen des Codes nicht benötigen.
Beim herumspielen stellen sie fest, dass es länger dauern wird als erwartet. Daher entschliessen Sie sich nun doch das Repository zu klonen um ihre Änderungen commiten zu können. Da die Arbeitskopie sehr gross ist und Sie bereits viele Dateien hinzugefügt, umbenannt oder gelöscht haben, wollen Sie nicht mit einem frischen Klon starten. Wie können Sie nun ihre Änderungen an die richtige Stelle commiten?
Die Lösung ist den .hg Ordner in das Hauptverzeichnis ihrer Arbeitskopie zu kopieren und diese Befehle auszuführen:
$ hg debugsetparent tip
$ hg debugrebuildstate
$ hg commit -Am "my snapshot"
2. Alternative check-ins erzeugen.
Falls Sie ein wenig wie ich bin, dann trauen sie sich selber nicht. Daher wollen Sie eine alternative Arbeit VOR dem löschen der anderen Alternative hinzufügen. Daher ist der gewöhnliche Ablauf mit einem Rollback nichts für sie.
Stattdessen können Sie diese einfachen Befehle nutzen:
$ hg debugsetparent tip^^
$ hg debugrebuildstate
So sind Sie auf dem Stand wie vor dem commit, allerdings ist der “falsche” commit noch immer im Repository.
3. Simulieren von Git’s —no-ff Merge mit anonymen Heads.
Die meisten Arbeitsabläufe von Git können einfach mit Mercurial nachvollzogen werden. Allerdings benötigen einige Befehle (gitflow) so genannte “non-fast-forward” Merges. Diese Merges können auch mit Mercurial gemacht werden, allerdings nur mit Named-Branches:
$ hg sl
$ echo x > x
$ hg ci -Am "base"
adding x
$ hg branch feature
marked working directory as branch feature
$ echo y > x
$ hg ci -m "feature"
$ hg up default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge feature
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg ci -m "merged"
$ hg glog
@ changeset: 2:e0502e1d12c6
|\ tag: tip
| | parent: 0:387ca709aeaf
| | parent: 1:205ec0dce78f
| | summary: merged
| |
| o changeset: 1:205ec0dce78f
|/ branch: feature
| summary: feature
|
o changeset: 0:387ca709aeaf
summary: base
Wie Sie an der obigen Ausgabe von graphlog sehen können enthält der Merge keine weitere Informationen neben der Angabe das 2 benannte Branches (‘default’ und ‘feature’) gemerged wurden. Mit Mercurial 1.5.1 können Sie dies nicht mehr mit anonymen Heads machen:
$ echo x > x
$ hg ci -Am "base"
adding x
$ echo y > x
$ hg ci -m "feature"
$ hg up 0
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg merge 1
abort: nothing to merge (use 'hg update' or check 'hg heads')
Was wollen Sie mit anonymen Head-Versionen machen? Nun, eine Möglichkeit um Branches von Git zu simulieren ist die bookmark Erweiterung. Unglücklicherweise nutzt bookmark (um die anonymen Heads zu benennen) immer noch anonyme Heads, daher kommt einem das Problem von oben erneut in den Weg:
$ hg bookmark master
$ hg bookmark feature -r 1
$ hg bookmark
* master 0:6965ee5bb884
feature 1:2061809a8e23
$ hg merge feature
abort: nothing to merge (use 'hg update' or check 'hg heads')
Die Lösung:
$ hg debugsetparents master feature
$ hg revert -a -r feature
reverting x
$ hg ci -m "merged"
$ hg glog
@ changeset: 2:0dfae55684f6
|\ tag: master
| | tag: tip
| | parent: 0:6965ee5bb884
| | parent: 1:2061809a8e23
| | summary: merged
| |
| o changeset: 1:2061809a8e23
|/ tag: feature
| summary: feature
|
o changeset: 0:6965ee5bb884
summary: base