revisions: when using prefixhexnode, ensure we prefix "0"
authorKyle Lippincott <spectral@google.com>
Tue, 16 Oct 2018 07:21:00 -0700
changeset 40341 d916ed3ca951
parent 40340 2d45b549392f
child 40342 6f152067ba57
revisions: when using prefixhexnode, ensure we prefix "0" Previously, if using `experimental.revisions.disambiguatewithin` (and it didn't include rev0), and '0' was the shortest identifier in that disambiguation set, we printed it as the shortest *without* a prefix. This was because we had logic to determine "if the prefix is a pure integer, but starts with 0, we don't need to prefix with 'x': 01 is not a synonym for revision #1", but didn't handle the case where prefix == 0 (which is a pure integer, and starts with 0... but it *is* "rev0"). Differential Revision: https://phab.mercurial-scm.org/D5113
mercurial/scmutil.py
tests/test-revisions.t
tests/test-template-functions.t
--- a/mercurial/scmutil.py	Wed Oct 03 16:45:24 2018 +0300
+++ b/mercurial/scmutil.py	Tue Oct 16 07:21:00 2018 -0700
@@ -477,8 +477,9 @@
         i = int(prefix)
         # if we are a pure int, then starting with zero will not be
         # confused as a rev; or, obviously, if the int is larger
-        # than the value of the tip rev
-        if prefix[0:1] == b'0' or i >= len(repo):
+        # than the value of the tip rev. We still need to disambiguate if
+        # prefix == '0', since that *is* a valid revnum.
+        if (prefix != b'0' and prefix[0:1] == b'0') or i >= len(repo):
             return False
         return True
     except ValueError:
--- a/tests/test-revisions.t	Wed Oct 03 16:45:24 2018 +0300
+++ b/tests/test-revisions.t	Tue Oct 16 07:21:00 2018 -0700
@@ -25,7 +25,7 @@
   > revisions.disambiguatewithin=not 4
   > EOF
   $ hg l
-  5:0
+  5:00
   4:7ba5d
   3:7b
   2:72
--- a/tests/test-template-functions.t	Wed Oct 03 16:45:24 2018 +0300
+++ b/tests/test-template-functions.t	Tue Oct 16 07:21:00 2018 -0700
@@ -804,6 +804,8 @@
   e777603221
   bcc7ff960b
   f7769ec2ab
+  $ hg log --template '{shortest(node, 1)}\n' -r null
+  00
   $ hg log --template '{node|shortest}\n' -l1
   e777
 
@@ -915,6 +917,55 @@
 
   $ cd ..
 
+Test prefixhexnode when the first character of the hash is 0.
+  $ hg init hashcollision2
+  $ cd hashcollision2
+  $ cat <<EOF >> .hg/hgrc
+  > [experimental]
+  > evolution.createmarkers=True
+  > EOF
+  $ echo 0 > a
+  $ hg ci -qAm 0
+  $ echo 21 > a
+  $ hg ci -qm 21
+  $ hg up -q null
+  $ hg log -r0: -T '{rev}:{node}\n'
+  0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
+  1:0cf177ba2b1dc3862a00fb81715fec90950201be
+
+ we need the 'x' prefix to ensure we aren't colliding with rev0. We identify
+ the collision with nullid if we aren't using disambiguatewithin, so we need to set
+ that as well.
+  $ hg --config experimental.revisions.disambiguatewithin='descendants(0)' \
+  >    --config experimental.revisions.prefixhexnode=yes \
+  >    log -r 1 -T '{rev}:{shortest(node, 0)}\n'
+  1:x0
+
+  $ hg debugobsolete 0cf177ba2b1dc3862a00fb81715fec90950201be
+  obsoleted 1 changesets
+  $ hg up -q 0
+  $ echo 61 > a
+  $ hg ci -m 61
+  $ hg log -r0: -T '{rev}:{node}\n'
+  0:b4e73ffab476aa0ee32ed81ca51e07169844bc6a
+  2:01384dde84b3a511ae0835f35ac40bd806c99bb8
+
+ we still have the 'x' prefix because '0' is still the shortest prefix, since
+ rev1's '0c' is hidden.
+  $ hg --config experimental.revisions.disambiguatewithin=0:-1-0 \
+  >    --config experimental.revisions.prefixhexnode=yes \
+  >    log -r 0:-1-0 -T '{rev}:{shortest(node, 0)}\n'
+  2:x0
+
+ we don't have the 'x' prefix on 2 because '01' is not a synonym for rev1.
+  $ hg --config experimental.revisions.disambiguatewithin=0:-1-0 \
+  >    --config experimental.revisions.prefixhexnode=yes \
+  >    log -r 0:-1-0 -T '{rev}:{shortest(node, 0)}\n' --hidden
+  1:0c
+  2:01
+
+  $ cd ..
+
 Test pad function
 
   $ cd r