Patchwork [5,of,8] bookmark: explicitly convert to 'node' during initialization

login
register
mail settings
Submitter Pierre-Yves David
Date June 8, 2017, 7:44 p.m.
Message ID <b8ad79e8c9b8f6cde6a9.1496951061@nodosa.octopoid.net>
Download mbox | patch
Permalink /patch/21256/
State Accepted
Headers show

Comments

Pierre-Yves David - June 8, 2017, 7:44 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@octobus.net>
# Date 1496870803 -3600
#      Wed Jun 07 22:26:43 2017 +0100
# Node ID b8ad79e8c9b8f6cde6a90df1ff2602238396b3f0
# Parent  656b0fe395c5592e073faa5c0fd95c5c56a0676c
# EXP-Topic perf
# Available At https://www.mercurial-scm.org/repo/users/marmoute/mercurial/
#              hg pull https://www.mercurial-scm.org/repo/users/marmoute/mercurial/ -r b8ad79e8c9b8
bookmark: explicitly convert to 'node' during initialization

We know the content of the file is supposed to be full hex. So we can do the
translation ourself and directly check if the node is known.

As nice side effect we now have proper error handling for invalid node value.

Before:
! wall 0.021580 comb 0.020000 user 0.020000 sys 0.000000 (best of 134)

After:
! wall 0.009342 comb 0.010000 user 0.010000 sys 0.000000 (best of 302)

Patch

diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
--- a/mercurial/bookmarks.py
+++ b/mercurial/bookmarks.py
@@ -50,7 +50,8 @@  class bmstore(dict):
     def __init__(self, repo):
         dict.__init__(self)
         self._repo = repo
-        lookup = repo.changelog.lookup
+        nm = repo.changelog.nodemap
+        tonode = bin #force local lookup
         try:
             bkfile = _getbkfile(repo)
             for line in bkfile:
@@ -62,11 +63,16 @@  class bmstore(dict):
                                  % line)
                     continue
                 sha, refspec = line.split(' ', 1)
-                refspec = encoding.tolocal(refspec)
                 try:
-                    self[refspec] = lookup(sha)
-                except LookupError:
-                    pass
+                    node = tonode(sha)
+                    if node in nm:
+                        refspec = encoding.tolocal(refspec)
+                        self[refspec] = node
+                except (TypeError, ValueError):
+                    # - bin(...) can raise TypeError
+                    # - node in nm can raise ValueError for non-20-bytes entry
+                    repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
+                                 % line)
         except IOError as inst:
             if inst.errno != errno.ENOENT:
                 raise
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -700,7 +700,7 @@  test wrongly formated bookmark
 
 test missing revisions
 
-  $ echo "925d80f479bc z" > .hg/bookmarks
+  $ echo "925d80f479b925d80f479bc925d80f479bccabab z" > .hg/bookmarks
   $ hg book
   no bookmarks set