Nicht gemeinsame Änderungen finden

posted by Steve Losh on December 9, 2009

Dieser Beitrag wurde durch eine E-Mail auf der mercurial-devel Mailing Liste inspiriert.

Die Frage lautet: Wie können feststellen, welche Änderungen in Revision X aber nicht in Y enthalten sind? Dies kann nützlich sein wenn Sie wissen wollen, was sich zwischen 2 Versionen einer Software verändert hat.

Dies tönt nach einer einfachen Aufgabe, allerdings gibt es einige Dinge die Sie beachten müssen.

Hinweis: In diesem Tipp verwende ich den Alias shortlog an der Stelle des normalen hg log Befehls. Der Alias ist eine Aufruf von hg log um Parameter für eine lesbarere Ausgabe. Daher wird alles gleich funktionieren wie mit hg log. Sie können daher den Befehl verwenden, der ihnen besser gefällt.

Der einfache (und falsche) Weg

Lassen Sie uns mit dem einfachsten Weg zum auflisten von Revisionen beginnen: die Option --rev. Wenn Sie ein einfaches Repository haben, wird der Graf so aussehen:

$ hg glog
o  4 Fix another bug. (6 seconds ago by Steve Losh) tip 
|
o  3 Fix a bug. (16 seconds ago by Steve Losh)  
|
@  2 Add another simple feature. (34 seconds ago by Steve Losh)  
|
o  1 Add a simple feature. (40 seconds ago by Steve Losh)  
|
o  0 Initial revision. (7 minutes ago by Steve Losh)

Wenn Sie auf Revision 2 stehen und wissen wollen welche Änderungen bei einem Update auf tip kommen, können Sie diesen Befehl nutzen:

 $ hg slog --rev 2:tip
 2 Add another simple feature. (5 minutes ago by Steve Losh) 
 3 Fix a bug. (5 minutes ago by Steve Losh) 
 4 Fix another bug. (5 minutes ago by Steve Losh) tip

Wie Sie sehen können, enthält die Ausgabe auch die Revision 2. Diese sollte nicht gezeigt werden, da Sie diese ja bereits haben. Dies mag keine grosse Sache sein, da Sie diese einfach ignorieren können.

Allerdings funktioniert dieser Ansatz nicht wenn Sie mehrere Äste haben, an denen gleichzeitig gearbeitet wurde. Als Beispiel:

$ hg glog
@  6 Fix a critical bug. (1 second ago by Steve Losh) tip 
|
| o  5 Start the rewrite of the UI. (24 seconds ago by Steve Losh)  ui-rewrite
| |
o |  4 Fix another bug. (8 minutes ago by Steve Losh)  
| |
o |  3 Fix a bug. (8 minutes ago by Steve Losh)  
| |
o |  2 Add another simple feature. (9 minutes ago by Steve Losh)  
|/
o  1 Add a simple feature. (9 minutes ago by Steve Losh)  
|
o  0 Initial revision. (16 minutes ago by Steve Losh)

$ hg slog --rev 2:tip
2 Add another simple feature. (9 minutes ago by Steve Losh) 
3 Fix a bug. (9 minutes ago by Steve Losh) 
4 Fix another bug. (9 minutes ago by Steve Losh) 
5 Start the rewrite of the UI. (54 seconds ago by Steve Losh) 
6 Fix a critical bug. (31 seconds ago by Steve Losh) tip

In der Ausgabe von hg slog erscheint die Änderungen 5. Diese liegt auf einem separaten Ast und ein update von 2 zu tip (6) wird keine Änderungen von 5 enthalten.

Dies weil Sie Mercurial einen Bereich von Änderungen angegeben haben, die es in der genannten Reihenfolge abarbeiten wird. Dies bedeutet das 1:4 eigentlich “1, 2, 3 und 4 egal auf welchem Ast” meint.

Mit einigen zusätzlichen Optionen bei hg log können wir eine bessere Ausgabe bekommen.

Der richtige Weg

Wenn wir einen Schritt zurück machen und das zu lösende Problem nochmals betrachten, lässt sich dies auf eine einfache Definition reduzieren. Wir wollen alle Änderungen,

Um das erste Problem zu lösen, können wir die Optionen --rev und --follow kombinieren. Dies sieht so aus:

$ hg slog --rev tip:0 --follow
6 Fix a critical bug. (11 minutes ago by Steve Losh) tip
4 Fix another bug. (20 minutes ago by Steve Losh) 
3 Fix a bug. (20 minutes ago by Steve Losh) 
2 Add another simple feature. (20 minutes ago by Steve Losh) 
1 Add a simple feature. (21 minutes ago by Steve Losh) 
0 Initial revision. (28 minutes ago by Steve Losh)

Diesmal wird die Änderung (5) im anderen Ast nicht angezeigt.

Die Verwendung von --rev ZIEL:0 mit --follow bedeutet “zeige mir alle Änderungen die Vorgänger von ZIEL sind”. Sie können sich mittels hg help log die Details der einzelnen Optionen anzeigen lassen.

Wir haben noch eine Aufgabe zu lösen — wir wollen die Änderungen entfernen, die bereits in unserer aktuellen Version enthalten sind:

$ hg slog --rev tip:0 --follow --prune 2
6 Fix a critical bug. (16 minutes ago by Steve Losh) tip
4 Fix another bug. (25 minutes ago by Steve Losh) 
3 Fix a bug. (25 minutes ago by Steve Losh)

Geschafft! Die Änderungen 6, 4 und 3 sind die Änderungen, die ein Update von 2 auf 6 in unserem Beispiel bringen wird.

Die allgemeine Form dieses Befehls sieht so aus:

hg slog --rev ZIEL:0 --follow --prune QUELLE

Natürlich können Sie auch die normalen Abkürzungen dazu verwenden. Um zu sehen was von der aktuellen Version auf tip an Änderungen ansteht, können Sie diesen Befehl nutzen:

hg slog -r tip:0 -fP .

Hinweis: Dieser Befehl funktioniert nicht wenn Sie “rückwärts” aktualisieren wollen. Es ist nur möglich zu zeigen was zusätzlich an Änderungen kommt. Es zeigt nicht welche Änderungen in QUELLE aber nicht in ZIEL vorhanden ist.

Wie können Sie sagen welche Änderungen in Revision X aber nicht in Y enthalten sind?