1

I'd like to find all differences between two mercurial revisions. I'd primarily like to see the history of the differences (i.e. the changeset log messages), not the internal details of what changed in the files.

Example: compare revisions 105 and 106

   /---101---103---105 
100         \
   \---102---104---106

Here, revision 106 includes changesets 106,104 and 102 which 105 doesn't have, and 105 in turn includes 103 and 105 that 106 doesn't have. How can I easily get this list; ideally taking into account grafts too?

The following revision set query almost works:

(ancestors(105) - ancestors(106)) + (ancestors(106) - ancestors(105))

However, that's a fairly long query for something that seems like a fairly common question: why exactly does this branch differ from my local version? I also believe it fails to take into account grafts and it unfortunately includes uninteresting changesets such as merges.

Bonus points for including the git equivalent.

Edit: The reason I want this is to explain to humans how these versions differ. I've got a complex source tree, and I need to be able to tell people that version X includes features A & B and bugfix P, but version Y includes features C & D and bugfix Q - and that they're otherwise the same.

If I go back to my example: merges themselves aren't interesting (so in the example above 104 isn't interesting), but the changesets the merges consist of are very interesting - meaning 101 and 102. Merges combine lots of changes into one changeset that lacks reasonable log information. In particular, if I just find the nearest ancestor, I'd find 101, and then it'd look like 102 isn't of particular interest. In terms of the actual patches applied, this information is complete - I don't need to see how merge changeset 104 was constructed, only the result. However, if I want to know why it contains those changes, I need the log messages from 102.

Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166
  • You forgot only exclude (for **perfect** result) only mergesets (merges of ancestors of nodes in question) – Lazy Badger Feb 12 '13 at 08:35
  • I'm not sure I understand - can you give an example? – Eamon Nerbonne Feb 12 '13 at 14:16
  • 1
    If you want to know only **changesets, which introduced differences between two nodes** you have to exclude (at least) mergesets, because **mergesets are only mirrors** of changes from p2() line into p1() – Lazy Badger Feb 12 '13 at 14:29
  • You say that "how exactly does this branch differ from my local version?" is a common question, and you're right, it does, but the answer to that is a simple one with diff. You dismiss that as "the internal details" but really it's the *only* meaningful comparison. In a repo without any merges you might be able to consider "under the changes you have that I don't and apply the changes I have that you don't" to be a *path* from one to another, but once merges are in play that's attractive but not meaningful -- that's why it's a hard list to get, because it's not actually useful. :( – Ry4an Brase Feb 13 '13 at 02:27
  • 1
    @Ry4an: the example I give includes merges; and is very meaningful to know which changesets are different since those changesets include log messages which explain which bugs were fixes and which functionality added. (Indeed the merges themselves aren't interesting, but the changesets they consist of are). In other words, this query lets me see in what high-level way the two heads differ. The diff is useless for this; it's way too low level. – Eamon Nerbonne Feb 13 '13 at 10:19
  • @LazyBadger: good point; I'll update the Q – Eamon Nerbonne Feb 13 '13 at 11:10

1 Answers1

0

Hrm, I've not tested it, but would:

ancestor(X,Y)::X + ancestor(X,Y)::Y

get you the same list. I think it would, and would also likely be faster.

Ry4an Brase
  • 78,112
  • 7
  • 148
  • 169
  • No, in will be another list (at least logically) – Lazy Badger Feb 12 '13 at 08:27
  • This would find the common ancestor and list all changes from it upto X and resp. Y. However, it would often include way too many changesets, namely those that both share. For example, using the diagram from the question, this would include 100 and 101 on the 106 side even though 105 already includes those. – Eamon Nerbonne Feb 12 '13 at 14:21
  • But that has highlighted a way to shorten the query - `(ancestors(105) - ancestors(106)) + (ancestors(106) - ancestors(105))` should be the same as `(::105 - ::106) + (::106 - ::105)` according to the help – Steve Kaye Feb 14 '13 at 08:03