[PATCH 1 of 2] parents: correct help revset replacements

timeless timeless at mozdev.org
Wed Dec 23 19:57:07 UTC 2015


# HG changeset patch
# User timeless <timeless at mozdev.org>
# Date 1450897654 0
#      Wed Dec 23 19:07:34 2015 +0000
# Node ID 362b7b756dbc8e6e3fc7dfbcc8f0e7cc2fcc6955
# Parent  e2aa9c4030c4109e5efa50462ffc6048ca30106f
parents: correct help revset replacements

Implementing `hg parents -r REV FILE` correctly is hard.

The output can be 0, 1, or 2 revs.

First, you can't use parents(), because it sorts its output...

Consider:
echo $a
echo par at rev: `hg log -r "parents($a)" -q`
echo p12 at rev: `hg log -r "p1($a)+p2($a)" -q`
echo parents: `hg parents -q -r $a`

(Merge 1 into 0)
3
par at rev: 0:d9612eafe8ec 1:070fe4290d06
p12 at rev: 0:d9612eafe8ec 1:070fe4290d06
parents: 0:d9612eafe8ec 1:070fe4290d06

(Merge 4 into 5)
6
par at rev: 4:db73392995c3 5:c26e7dd67644
p12 at rev: 5:c26e7dd67644 4:db73392995c3
parents: 5:c26e7dd67644 4:db73392995c3

(Merge 7 into 8)
9
par at rev: 7:d84f47462f70 8:9597bcab36e0
p12 at rev: 8:9597bcab36e0 7:d84f47462f70
parents: 8:9597bcab36e0 7:d84f47462f70

You also can't use parents or/p1/p2 alone with a set, as in:
-r "parents(::REV and file(FILE))"
-r "parents(::REV - REV and file(FILE))"
... because each will return all parents for each candidate revision,
and the :: gives too many candidates.

Thus, we need a max and a p1/p2.

Also, anything of this form:
max(::REV - REV and file(FILE))
... is wrong, because max will return only one revision, and for
a proper parents, you need to return two occasionally.

Lastly, it doesn't help that `hg parents -r REV FILE` is buggy
due to a quirk in filelogs.

Here's a repository to consider when evaluating whether your
revset is correct:

$ hg log -G --template '{rev} {files}\n';
@  10 a
|
o    9 a b
|\
| o  8 a
| |
o |  7 a
| |
+---o  6 b
| |/
| o  5 b
| |
o |  4 b
| |
+---o  3
| |/
+---o  2
| |/
| o  1 b
|
o  0 a

revs 4 and 5 create a conflict.
The conflict is resolved in the same way by both 6 and 9.

You would hope that parents around 9/10 would point to 9,
but `hg parents` will point to 6 due to the aforementioned bug.

Here's the winning solution test script and its output.

echo $a;
echo rp12-max: `hg log -r "max(::p1($a) and file(b)) + max(::p2($a) and file(b))" -q` 2> /dev/null;
echo expected: `hg parents -q -r $a b` 2> /dev/null;

Note that for 10, the output differs, but again, this is because
of the aforementioned bug. The rp12-max output is "correct",
whereas "expected" is just an unfortunate bug. The abort output
is due to something else. I'm not sure why someone thought it
was important to abort to stdio instead of stderr, but that's
really not my problem here.

10
rp12-max: 9:184ebefc2fce
expected: 6:dd558142b03f
9
rp12-max: 5:c26e7dd67644 4:db73392995c3
expected: 5:c26e7dd67644 4:db73392995c3
8
rp12-max: 5:c26e7dd67644
expected: 5:c26e7dd67644
7
rp12-max: 4:db73392995c3
expected: 4:db73392995c3
6
rp12-max: 5:c26e7dd67644 4:db73392995c3
expected: 5:c26e7dd67644 4:db73392995c3
5
rp12-max: 1:070fe4290d06
expected: 1:070fe4290d06
4
rp12-max:
abort: 'b' not found in manifest!
expected:
3
rp12-max: 1:070fe4290d06
expected: 1:070fe4290d06
2
rp12-max: 1:070fe4290d06
expected: 1:070fe4290d06
1
rp12-max:
abort: 'b' not found in manifest!
expected:
0
rp12-max:
abort: 'b' not found in manifest!
expected:

diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -5300,10 +5300,10 @@
 
     This command is equivalent to::
 
-        hg log -r "parents()" or
-        hg log -r "parents(REV)" or
-        hg log -r "max(file(FILE))" or
-        hg log -r "max(::REV and file(FILE))"
+        hg log -r "p1()+p2()" or
+        hg log -r "p1(REV)+p2(REV)" or
+        hg log -r "max(::p1() and file(FILE))+max(::p2() and file(FILE))" or
+        hg log -r "max(::p1(REV) and file(FILE))+max(::p2(REV) and file(FILE))"
 
     See :hg:`summary` and :hg:`help revsets` for related information.
 


More information about the Mercurial-devel mailing list