Patchwork [9,of,9] revset: abort the query when there is no revision for "id()" (BC)

login
register
mail settings
Submitter Katsunori FUJIWARA
Date March 29, 2015, 6:34 p.m.
Message ID <36a8bb32c9bf6377be95.1427654071@juju>
Download mbox | patch
Permalink /patch/8361/
State Changes Requested
Headers show

Comments

Katsunori FUJIWARA - March 29, 2015, 6:34 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1427653752 -32400
#      Mon Mar 30 03:29:12 2015 +0900
# Node ID 36a8bb32c9bf6377be95ef82c676665186892f79
# Parent  8a0e73ddbd401236f42f0afd65f254c4cdcdce08
revset: abort the query when there is no revision for "id()" (BC)

Before this patch, there are difference between "FULLHASH",
"id(FULLHASH)", "PARTIALHASH" and "id(PARTIALHASH)":

    target      FULLHASH     id(FULLHASH) PARTIALHASH  id(PARTIALHASH)
    ----------- ------------ ------------ ------------ ------------
    known       pass         pass         pass         pass
    hidden      abort (*1)   abort (*1)   abort (*1)   pass (=> empty set)
    unknown     abort        abort        abort        pass (=> empty set)

    (*1) abort with "use --hidden" hint

For equivalence between them, "id(PARTIALHASH)" should abort the query
for hidden or unknown revisions, even though this may break backward
compatibility for existing tools, which expect that "id(PARTIALHASH)"
doesn't abort the query in any cases.

In addition to it, "id(FULLHASH)" may cause unexpected matching
against bookmark, (head of) branch or tag in 40 characters, because
"repo[n]" implies looking up in namespaces, too.

This patch uses "context.findbyhash()" (via repo) to abort if the
target revision doesn't exist or isn't visible.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -1287,21 +1287,18 @@  def named(repo, subset, x):
 def node_(repo, subset, x):
     """``id(string)``
     Revision non-ambiguously specified by the given hex string prefix.
+
+    This predicate aborts the query, if the specified string doesn't
+    refer any (visible) existing revision. Use this with ``present()``
+    to continue the query even in such case.
     """
     # i18n: "id" is a keyword
     l = getargs(x, 1, 1, _("id requires one argument"))
     # i18n: "id" is a keyword
     n = getstring(l[0], _("id requires a string"))
-    if len(n) == 40:
-        rn = repo[n].rev()
-    else:
-        rn = None
-        pm = repo.changelog._partialmatch(n)
-        if pm is not None:
-            rn = repo.changelog.rev(pm)
-
-    if rn is None:
-        return baseset()
+
+    n, rn = repo.findbyhash(n, abort=True)
+
     result = baseset([rn])
     return result & subset
 
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -194,8 +194,32 @@  check that various commands work well wi
   [255]
   $ hg debugrevspec --hidden 'rev(4)'
   4
+  $ hg debugrevspec 'ca819180edb99ed25ceafb3e9584ac287e240b00'
+  abort: hidden revision 'ca819180edb99ed25ceafb3e9584ac287e240b00'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg debugrevspec 'id(ca819180edb99ed25ceafb3e9584ac287e240b00)'
+  abort: hidden revision 'ca819180edb99ed25ceafb3e9584ac287e240b00'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg debugrevspec 'ca819180edb9'
+  abort: hidden revision 'ca819180edb9'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg debugrevspec 'id(ca819180edb9)'
+  abort: hidden revision 'ca819180edb9'!
+  (use --hidden to access hidden revisions)
+  [255]
+  $ hg debugrevspec --hidden 'id(ca819180edb99ed25ceafb3e9584ac287e240b00)'
+  4
+  $ hg debugrevspec --hidden 'id(ca819180edb9)'
+  4
   $ hg debugrevspec 'null'
   -1
+  $ hg debugrevspec 'id(0000000000000000000000000000000000000000)'
+  -1
+  $ hg debugrevspec 'id(000000000000)'
+  -1
 
 Check that public changeset are not accounted as obsolete:
 
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -488,6 +488,26 @@  min: empty on unordered set
   4
   $ log 'id(5)'
   2
+  $ log 'ffffffffffffffffffffffffffffffffffffffff'
+  abort: unknown revision 'ffffffffffffffffffffffffffffffffffffffff'!
+  [255]
+  $ log 'id(ffffffffffffffffffffffffffffffffffffffff)'
+  abort: unknown revision 'ffffffffffffffffffffffffffffffffffffffff'!
+  [255]
+  $ log 'ffffffffffff'
+  abort: unknown revision 'ffffffffffff'!
+  [255]
+  $ log 'id(ffffffffffff)'
+  abort: unknown revision 'ffffffffffff'!
+  [255]
+  $ log 'present(ffffffffffffffffffffffffffffffffffffffff)'
+  $ log 'present(id(ffffffffffffffffffffffffffffffffffffffff))'
+  $ log 'present(id(ffffffffffff))'
+  $ hg bookmarks -r 0 ffffffffffffffffffffffffffffffffffffffff
+  $ log 'id(ffffffffffffffffffffffffffffffffffffffff)'
+  abort: unknown revision 'ffffffffffffffffffffffffffffffffffffffff'!
+  [255]
+  $ hg bookmarks -d ffffffffffffffffffffffffffffffffffffffff
   $ log 'only(9)'
   8
   9