Source

hgtip-content / beginner / 2009-12-09-finding-uncommon-changesets.html

{% extends "_tip.html" %}
{%hyde
    title: Nicht gemeinsame Änderungen finden
    author_name: Steve Losh
    author_link: http://stevelosh.com/
    created: 2009-12-09
%}


{% block excerpt %}
Wie können Sie sagen welche Änderungen in Revision `X` aber **nicht** in 
`Y` enthalten sind?
{% endblock %}


{% block tip %}

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

[email]: http://www.selenic.com/pipermail/mercurial-devel/2009-December/017417.html
[ml]: http://mercurial.selenic.com/wiki/MailingLists

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][slog] 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.

[slog]: /tips/beginner/2009-10-07-shortlog-for-fun-and-profit/

### 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,

* die in der Zielversion und deren VorgÄngern enthalten ist.
* die aber **nicht** in der Ausgangsversion sind.

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.



{% endblock %}