The revsets help mentions
"x::y" A DAG range, meaning all changesets that are descendants of x and ancestors of y, including x and y themselves. If the first endpoint is left out, this is equivalent to "ancestors(y)", if the second is left out it is equivalent to "descendants(x)". An alternative syntax is "x..y".
"x:y" All changesets with revision numbers between x and y, both inclusive. Either endpoint can be left out, they default to 0 and tip.
"x % y" Changesets that are ancestors of x but not ancestors of y (i.e. ::x - ::y). This is shorthand notation for "only(x, y)" (see below). The second argument is optional and, if left out, is equivalent to "only(x)".
It is not clear what the results are differentiated. In general, "x % y" returns what I want to choose, but I want to understand others.