2015-02-18 06:02:09 +03:00
|
|
|
# gitrevset.py
|
2014-10-29 09:06:11 +03:00
|
|
|
#
|
|
|
|
# Copyright 2014 Facebook, Inc.
|
2015-03-08 22:22:25 +03:00
|
|
|
"""map a git hash to a Mercurial hash:
|
2014-10-29 09:06:11 +03:00
|
|
|
|
|
|
|
$ hg log -r 'gitnode($HASH)'
|
|
|
|
$ hg id -r 'gitnode($HASH)'
|
|
|
|
|
|
|
|
shortversion:
|
|
|
|
|
|
|
|
$ hg log -r 'g$HASH'
|
|
|
|
$ hg id -r 'g$HASH'
|
|
|
|
|
|
|
|
"""
|
2014-09-23 05:58:36 +04:00
|
|
|
from mercurial import extensions
|
2015-02-17 21:53:25 +03:00
|
|
|
from mercurial import error
|
2014-09-09 02:36:12 +04:00
|
|
|
from mercurial import hg
|
templates: fix help messages for template keywords
Summary:
Many of the template keywords in our extensions were being registered
incorrectly, causing their help output to be rendered incorrectly in the
"hg help templates" output. The ones in smartlog.py were particularly bad, as
most of them showed only their description, without displaying the name of the
template. In smartlog.py only singlepublicsuccessor was being displayed
correctly, because it's docstring explicitly included it's own name at the
start.
This fixes all of our extensions to consistently use the
registrar.templatekeyword() decorator to register the keywords. This decorator
automatically prefixes the help message with the keyword name. The
mercurial/extensions.py code will explicitly check to see if an extension
contains an "templatekeyword" attribute, and if so it will register any
keywords contained in this registry after calling extsetup().
Test Plan:
Added new unit tests to check the output of "hg help templates" for the
affected keywords.
Reviewers: #sourcecontrol, kulshrax, ikostia, rmcelroy
Reviewed By: rmcelroy
Subscribers: rmcelroy, net-systems-diffs@, yogeshwer, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D4427729
Signature: t1:4427729:1484831476:17b478a5e867dfc3f85402588c381bf8b1831107
2017-01-19 23:52:54 +03:00
|
|
|
from mercurial import registrar
|
2014-09-09 02:36:12 +04:00
|
|
|
from mercurial import revset
|
|
|
|
from mercurial.i18n import _
|
2014-09-23 05:58:36 +04:00
|
|
|
import re
|
|
|
|
|
|
|
|
githashre = re.compile('g([0-9a-fA-F]{40,40})')
|
2014-09-09 02:36:12 +04:00
|
|
|
|
templates: fix help messages for template keywords
Summary:
Many of the template keywords in our extensions were being registered
incorrectly, causing their help output to be rendered incorrectly in the
"hg help templates" output. The ones in smartlog.py were particularly bad, as
most of them showed only their description, without displaying the name of the
template. In smartlog.py only singlepublicsuccessor was being displayed
correctly, because it's docstring explicitly included it's own name at the
start.
This fixes all of our extensions to consistently use the
registrar.templatekeyword() decorator to register the keywords. This decorator
automatically prefixes the help message with the keyword name. The
mercurial/extensions.py code will explicitly check to see if an extension
contains an "templatekeyword" attribute, and if so it will register any
keywords contained in this registry after calling extsetup().
Test Plan:
Added new unit tests to check the output of "hg help templates" for the
affected keywords.
Reviewers: #sourcecontrol, kulshrax, ikostia, rmcelroy
Reviewed By: rmcelroy
Subscribers: rmcelroy, net-systems-diffs@, yogeshwer, mjpieters
Differential Revision: https://phabricator.intern.facebook.com/D4427729
Signature: t1:4427729:1484831476:17b478a5e867dfc3f85402588c381bf8b1831107
2017-01-19 23:52:54 +03:00
|
|
|
templatekeyword = registrar.templatekeyword()
|
|
|
|
|
|
|
|
@templatekeyword("gitnode")
|
2014-09-09 02:36:12 +04:00
|
|
|
def showgitnode(repo, ctx, templ, **args):
|
|
|
|
"""Return the git revision corresponding to a given hg rev"""
|
2017-03-29 17:13:41 +03:00
|
|
|
hexgitnode = _lookup_node(repo, ctx.hex(), from_scm_type='hg')
|
|
|
|
# templates are expected to return an empty string when no
|
|
|
|
# data exists
|
|
|
|
return hexgitnode.encode('hex') if hexgitnode else ''
|
2014-09-09 02:36:12 +04:00
|
|
|
|
|
|
|
def gitnode(repo, subset, x):
|
2014-10-29 09:06:11 +03:00
|
|
|
"""``gitnode(id)``
|
|
|
|
Return the hg revision corresponding to a given git rev."""
|
2014-09-09 02:36:12 +04:00
|
|
|
l = revset.getargs(x, 1, 1, _("id requires one argument"))
|
|
|
|
n = revset.getstring(l[0], _("id requires a string"))
|
2014-10-09 03:48:59 +04:00
|
|
|
|
2017-03-29 17:13:41 +03:00
|
|
|
hexhgnode = _lookup_node(repo, n, from_scm_type='git')
|
|
|
|
if not hexhgnode:
|
|
|
|
raise error.RepoLookupError(_("unknown revision '%s'") % n)
|
|
|
|
|
|
|
|
rev = repo[hexhgnode].rev()
|
|
|
|
return subset.filter(lambda r: r == rev)
|
|
|
|
|
|
|
|
def _lookup_node(repo, hexnode, from_scm_type):
|
|
|
|
gitlookupnode = '_gitlookup_%s_%s' % (from_scm_type, hexnode)
|
|
|
|
|
|
|
|
# ui.expandpath('default') returns 'default' if there is no default
|
|
|
|
# path. This can be the case when command is ran on the server.
|
|
|
|
# In that case let's run lookup() command locally.
|
2015-02-17 21:44:26 +03:00
|
|
|
try:
|
2017-03-29 17:13:41 +03:00
|
|
|
return repo.lookup(gitlookupnode)
|
|
|
|
except error.RepoLookupError:
|
|
|
|
# Note: RepoLookupError is caught here because repo.lookup()
|
|
|
|
# can throw only this exception.
|
|
|
|
peerpath = repo.ui.expandpath('default')
|
|
|
|
|
|
|
|
# sshing can cause junk 'remote: ...' output to stdout, so we need to
|
|
|
|
# redirect it temporarily so automation can parse the result easily.
|
|
|
|
oldfout = repo.ui.fout
|
|
|
|
try:
|
|
|
|
repo.baseui.fout = repo.ui.ferr
|
|
|
|
remoterepo = hg.peer(repo, {}, peerpath)
|
|
|
|
return remoterepo.lookup(gitlookupnode)
|
|
|
|
except error.RepoError:
|
|
|
|
# Note: RepoError can be thrown by hg.peer(), RepoLookupError
|
|
|
|
# can be thrown by remoterepo.lookup(). RepoLookupError is a
|
|
|
|
# subclass of RepoError so catching just error.RepoError is enough.
|
|
|
|
return None
|
|
|
|
finally:
|
|
|
|
repo.baseui.fout = oldfout
|
2014-09-09 02:36:12 +04:00
|
|
|
|
2014-09-23 05:58:36 +04:00
|
|
|
def overridestringset(orig, repo, subset, x):
|
|
|
|
m = githashre.match(x)
|
|
|
|
if m is not None:
|
|
|
|
return gitnode(repo, subset, ('string', m.group(1)))
|
|
|
|
return orig(repo, subset, x)
|
|
|
|
|
2014-09-09 02:36:12 +04:00
|
|
|
def extsetup(ui):
|
|
|
|
revset.symbols['gitnode'] = gitnode
|
2014-09-23 05:58:36 +04:00
|
|
|
extensions.wrapfunction(revset, 'stringset', overridestringset)
|
2015-05-08 03:46:30 +03:00
|
|
|
revset.symbols['stringset'] = revset.stringset
|
|
|
|
revset.methods['string'] = revset.stringset
|
|
|
|
revset.methods['symbol'] = revset.stringset
|