mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 09:17:30 +03:00
10bb5a144e
Summary: Migrate away from some uses of revision numbers. Some dead code in discovery.py is removed. I also fixed some test issues when I run tests locally. Reviewed By: sfilipco Differential Revision: D20155399 fbshipit-source-id: bfdcb57f06374f9f27be51b0980652ef50a2c8e0
116 lines
3.5 KiB
Python
116 lines
3.5 KiB
Python
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2.
|
|
|
|
"""map a git hash to a Mercurial hash:
|
|
|
|
$ hg log -r "gitnode($HASH)"
|
|
$ hg id -r "gitnode($HASH)"
|
|
|
|
short version:
|
|
|
|
$ hg log -r "g$HASH"
|
|
$ hg id -r "g$HASH"
|
|
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import re
|
|
|
|
from edenscm.mercurial import error, extensions, hg, namespaces, registrar, revset
|
|
from edenscm.mercurial.i18n import _
|
|
from edenscm.mercurial.node import hex
|
|
|
|
|
|
namespacepredicate = registrar.namespacepredicate()
|
|
revsetpredicate = registrar.revsetpredicate()
|
|
|
|
githashre = re.compile("g([0-9a-fA-F]{40})")
|
|
|
|
templatekeyword = registrar.templatekeyword()
|
|
|
|
|
|
@templatekeyword("gitnode")
|
|
def showgitnode(repo, ctx, templ, **args):
|
|
"""Return the git revision corresponding to a given hg rev"""
|
|
# Try reading from commit extra first.
|
|
extra = ctx.extra()
|
|
if "hg-git-rename-source" in extra:
|
|
hexnode = extra.get("convert_revision")
|
|
if hexnode:
|
|
return hexnode
|
|
binnode = _lookup_node(repo, ctx.hex(), from_scm_type="hg")
|
|
# templates are expected to return an empty string when no
|
|
# data exists
|
|
return hex(binnode) if binnode else ""
|
|
|
|
|
|
@revsetpredicate("gitnode(id)")
|
|
def gitnode(repo, subset, x):
|
|
"""``gitnode(id)``
|
|
Return the hg revision corresponding to a given git rev."""
|
|
l = revset.getargs(x, 1, 1, _("id requires one argument"))
|
|
n = revset.getstring(l[0], _("id requires a string"))
|
|
|
|
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.
|
|
try:
|
|
result = 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)
|
|
result = 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
|
|
|
|
# Sanity check - result must be 20 chars
|
|
if len(result) != 20:
|
|
return None
|
|
else:
|
|
return result
|
|
|
|
|
|
@namespacepredicate("gitrev", priority=75)
|
|
def _getnamespace(_repo):
|
|
return namespaces.namespace(
|
|
listnames=lambda repo: [], namemap=_gitlookup, nodemap=lambda repo, node: []
|
|
)
|
|
|
|
|
|
def _gitlookup(repo, gitrev):
|
|
def _gittohg(githash):
|
|
return list(repo.nodes("gitnode(%s)" % githash))
|
|
|
|
m = githashre.match(gitrev)
|
|
if m is not None:
|
|
return _gittohg(m.group(1))
|
|
else:
|
|
return []
|