D3371: scmutil: make shortesthexnodeidprefix() take a full binary nodeid
This revision was automatically updated to reflect the committed changes. Closed by commit rHG1f473df0dffe: scmutil: make shortesthexnodeidprefix() take a full binary nodeid (authored by martinvonz, committed by ). CHANGED PRIOR TO COMMIT https://phab.mercurial-scm.org/D3371?vs=8286&id=8303#toc REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3371?vs=8286&id=8303 REVISION DETAIL https://phab.mercurial-scm.org/D3371 AFFECTED FILES hgext/show.py mercurial/scmutil.py mercurial/templatefuncs.py tests/test-command-template.t CHANGE DETAILS diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3900,6 +3900,21 @@ $ hg log -r 'wdir()' -T '{node|shortest}\n' + $ hg log --template '{shortest("f")}\n' -l1 + f + + $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1 + 0123456789012345678901234567890123456789 + + $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1 + 01234567890123456789012345678901234567890123456789 + + $ hg log --template '{shortest("not a hex string")}\n' -l1 + not a hex string + + $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1 + not a hex string, but it's 40 bytes long + $ cd .. Test shortest(node) with the repo having short hash collision: diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py +++ b/mercurial/templatefuncs.py @@ -10,6 +10,9 @@ import re from .i18n import _ +from .node import ( +bin, +) from . import ( color, encoding, @@ -579,15 +582,29 @@ # i18n: "shortest" is a keyword raise error.ParseError(_("shortest() expects one or two arguments")) -node = evalstring(context, mapping, args[0]) +hexnode = evalstring(context, mapping, args[0]) minlength = 4 if len(args) > 1: minlength = evalinteger(context, mapping, args[1], # i18n: "shortest" is a keyword _("shortest() expects an integer minlength")) repo = context.resource(mapping, 'ctx')._repo +if len(hexnode) > 40: +return hexnode +elif len(hexnode) == 40: +try: +node = bin(hexnode) +except TypeError: +return hexnode +else: +try: +node = scmutil.resolvehexnodeidprefix(repo, hexnode) +except (error.LookupError, error.WdirUnsupported): +return hexnode +if not node: +return hexnode return scmutil.shortesthexnodeidprefix(repo, node, minlength) @templatefunc('strip(text[, chars])') diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -443,12 +443,12 @@ repo.changelog.rev(node) # make sure node isn't filtered return node -def shortesthexnodeidprefix(repo, hexnode, minlength=1): +def shortesthexnodeidprefix(repo, node, minlength=1): """Find the shortest unambiguous prefix that matches hexnode.""" # _partialmatch() of filtered changelog could take O(len(repo)) time, # which would be unacceptably slow. so we look for hash collision in # unfiltered space, which means some hashes may be slightly longer. -return repo.unfiltered().changelog.shortest(hexnode, minlength) +return repo.unfiltered().changelog.shortest(hex(node), minlength) def isrevsymbol(repo, symbol): """Checks if a symbol exists in the repo. diff --git a/hgext/show.py b/hgext/show.py --- a/hgext/show.py +++ b/hgext/show.py @@ -29,7 +29,6 @@ from mercurial.i18n import _ from mercurial.node import ( -hex, nullrev, ) from mercurial import ( @@ -448,8 +447,8 @@ if not revs: return minlen cl = repo.changelog -return max(len(scmutil.shortesthexnodeidprefix(repo, hex(cl.node(r)), - minlen)) for r in revs) +return max(len(scmutil.shortesthexnodeidprefix(repo, cl.node(r), minlen)) + for r in revs) # Adjust the docstring of the show command so it shows all registered views. # This is a bit hacky because it runs at the end of module load. When moved To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3371: scmutil: make shortesthexnodeidprefix() take a full binary nodeid
yuja added a comment. Queued thanks. > The shortest() template function depended on the behavior of > revlog._partialmatch() for these types of inputs: I guess some of them would be bug. INLINE COMMENTS > templatefuncs.py:605 > +except (error.LookupError, error.WdirUnsupported): > +return hexnode > +if not node: One minor bug in this patch. `hg log -T '{shortest(node|short)}\n' -r 'wdir()'` no longer works. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3371 To: martinvonz, #hg-reviewers Cc: yuja, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3371: scmutil: make shortesthexnodeidprefix() take a full binary nodeid
martinvonz updated this revision to Diff 8286. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D3371?vs=8256&id=8286 REVISION DETAIL https://phab.mercurial-scm.org/D3371 AFFECTED FILES hgext/show.py mercurial/scmutil.py mercurial/templatefuncs.py tests/test-command-template.t CHANGE DETAILS diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3900,6 +3900,21 @@ $ hg log -r 'wdir()' -T '{node|shortest}\n' + $ hg log --template '{shortest("f")}\n' -l1 + f + + $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1 + 0123456789012345678901234567890123456789 + + $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1 + 01234567890123456789012345678901234567890123456789 + + $ hg log --template '{shortest("not a hex string")}\n' -l1 + not a hex string + + $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1 + not a hex string, but it's 40 bytes long + $ cd .. Test shortest(node) with the repo having short hash collision: diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py +++ b/mercurial/templatefuncs.py @@ -26,6 +26,9 @@ templateutil, util, ) +from .node import ( +bin, +) from .utils import ( dateutil, stringutil, @@ -579,15 +582,29 @@ # i18n: "shortest" is a keyword raise error.ParseError(_("shortest() expects one or two arguments")) -node = evalstring(context, mapping, args[0]) +hexnode = evalstring(context, mapping, args[0]) minlength = 4 if len(args) > 1: minlength = evalinteger(context, mapping, args[1], # i18n: "shortest" is a keyword _("shortest() expects an integer minlength")) repo = context.resource(mapping, 'ctx')._repo +if len(hexnode) > 40: +return hexnode +elif len(hexnode) == 40: +try: +node = bin(hexnode) +except TypeError: +return hexnode +else: +try: +node = scmutil.resolvehexnodeidprefix(repo, hexnode) +except (error.LookupError, error.WdirUnsupported): +return hexnode +if not node: +return hexnode return scmutil.shortesthexnodeidprefix(repo, node, minlength) @templatefunc('strip(text[, chars])') diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -443,12 +443,12 @@ repo.changelog.rev(node) # make sure node isn't filtered return node -def shortesthexnodeidprefix(repo, hexnode, minlength=1): +def shortesthexnodeidprefix(repo, node, minlength=1): """Find the shortest unambiguous prefix that matches hexnode.""" # _partialmatch() of filtered changelog could take O(len(repo)) time, # which would be unacceptably slow. so we look for hash collision in # unfiltered space, which means some hashes may be slightly longer. -return repo.unfiltered().changelog.shortest(hexnode, minlength) +return repo.unfiltered().changelog.shortest(hex(node), minlength) def isrevsymbol(repo, symbol): """Checks if a symbol exists in the repo. diff --git a/hgext/show.py b/hgext/show.py --- a/hgext/show.py +++ b/hgext/show.py @@ -29,7 +29,6 @@ from mercurial.i18n import _ from mercurial.node import ( -hex, nullrev, ) from mercurial import ( @@ -448,8 +447,8 @@ if not revs: return minlen cl = repo.changelog -return max(len(scmutil.shortesthexnodeidprefix(repo, hex(cl.node(r)), - minlen)) for r in revs) +return max(len(scmutil.shortesthexnodeidprefix(repo, cl.node(r), minlen)) + for r in revs) # Adjust the docstring of the show command so it shows all registered views. # This is a bit hacky because it runs at the end of module load. When moved To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D3371: scmutil: make shortesthexnodeidprefix() take a full binary nodeid
martinvonz created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY The shortest() template function depended on the behavior of revlog._partialmatch() for these types of inputs: - non-hex strings - ambiguous strings - too long strings revlog._partialmatch() seems to return the input unchanged in these cases, but we shouldn't depend on such a low-level function to match the behavior we want in the user-facing template function. Instead, let's handle these cases in the template function and always pass a binary nodeid to _partialmatch(). REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D3371 AFFECTED FILES hgext/show.py mercurial/scmutil.py mercurial/templatefuncs.py tests/test-command-template.t CHANGE DETAILS diff --git a/tests/test-command-template.t b/tests/test-command-template.t --- a/tests/test-command-template.t +++ b/tests/test-command-template.t @@ -3900,6 +3900,21 @@ $ hg log -r 'wdir()' -T '{node|shortest}\n' + $ hg log --template '{shortest("f")}\n' -l1 + f + + $ hg log --template '{shortest("0123456789012345678901234567890123456789")}\n' -l1 + 0123456789012345678901234567890123456789 + + $ hg log --template '{shortest("01234567890123456789012345678901234567890123456789")}\n' -l1 + 01234567890123456789012345678901234567890123456789 + + $ hg log --template '{shortest("not a hex string")}\n' -l1 + not a hex string + + $ hg log --template '{shortest("not a hex string, but it'\''s 40 bytes long")}\n' -l1 + not a hex string, but it's 40 bytes long + $ cd .. Test shortest(node) with the repo having short hash collision: diff --git a/mercurial/templatefuncs.py b/mercurial/templatefuncs.py --- a/mercurial/templatefuncs.py +++ b/mercurial/templatefuncs.py @@ -26,6 +26,9 @@ templateutil, util, ) +from .node import ( +bin, +) from .utils import ( dateutil, stringutil, @@ -579,15 +582,29 @@ # i18n: "shortest" is a keyword raise error.ParseError(_("shortest() expects one or two arguments")) -node = evalstring(context, mapping, args[0]) +hexnode = evalstring(context, mapping, args[0]) minlength = 4 if len(args) > 1: minlength = evalinteger(context, mapping, args[1], # i18n: "shortest" is a keyword _("shortest() expects an integer minlength")) repo = context.resource(mapping, 'ctx')._repo +if len(hexnode) > 40: +return hexnode +elif len(hexnode) == 40: +try: +node = bin(hexnode) +except TypeError: +return hexnode +else: +try: +node = scmutil.resolvehexnodeidprefix(repo, hexnode) +except (error.LookupError, error.WdirUnsupported): +return hexnode +if not node: +return hexnode return scmutil.shortesthexnodeidprefix(repo, node, minlength) @templatefunc('strip(text[, chars])') diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -443,12 +443,12 @@ repo.changelog.rev(node) # make sure node isn't filtered return node -def shortesthexnodeidprefix(repo, hexnode, minlength=1): +def shortesthexnodeidprefix(repo, node, minlength=1): """Find the shortest unambiguous prefix that matches hexnode.""" # _partialmatch() of filtered changelog could take O(len(repo)) time, # which would be unacceptably slow. so we look for hash collision in # unfiltered space, which means some hashes may be slightly longer. -return repo.unfiltered().changelog.shortest(hexnode, minlength) +return repo.unfiltered().changelog.shortest(hex(node), minlength) def isrevsymbol(repo, symbol): """Checks if a symbol exists in the repo. diff --git a/hgext/show.py b/hgext/show.py --- a/hgext/show.py +++ b/hgext/show.py @@ -448,8 +448,8 @@ if not revs: return minlen cl = repo.changelog -return max(len(scmutil.shortesthexnodeidprefix(repo, hex(cl.node(r)), - minlen)) for r in revs) +return max(len(scmutil.shortesthexnodeidprefix(repo, cl.node(r), minlen)) + for r in revs) # Adjust the docstring of the show command so it shows all registered views. # This is a bit hacky because it runs at the end of module load. When moved To: martinvonz, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel