示例#1
0
文件: git2hg.py 项目: danchr/hg-git
def filter_refs(refs, heads):
    '''For a dictionary of refs: shas, if heads is None then return refs
    that match the heads. Otherwise, return refs that are heads or tags.

    '''
    filteredrefs = []
    if heads is not None:
        # contains pairs of ('refs/(heads|tags|...)/foo', 'foo')
        # if ref is just '<foo>', then we get ('foo', 'foo')
        stripped_refs = [
            (r, r[r.find(b'/', r.find(b'/') + 1) + 1 :]) for r in refs
        ]
        for h in heads:
            if h.endswith(b'/*'):
                prefix = h[:-1]  # include the / but not the *
                r = [
                    pair[0]
                    for pair in stripped_refs
                    if pair[1].startswith(prefix)
                ]
                r.sort()
                filteredrefs.extend(r)
            else:
                r = [pair[0] for pair in stripped_refs if pair[1] == h]
                if not r:
                    msg = _(b"unknown revision '%s'") % h
                    raise error.RepoLookupError(msg)
                elif len(r) == 1:
                    filteredrefs.append(r[0])
                else:
                    msg = _(b"ambiguous reference %s: %s")
                    msg %= (
                        h,
                        b', '.join(sorted(r)),
                    )
                    raise error.RepoLookupError(msg)
    else:
        for ref, sha in refs.items():
            if not ref.endswith(ANNOTATED_TAG_SUFFIX) and (
                ref.startswith(LOCAL_BRANCH_PREFIX)
                or ref.startswith(LOCAL_TAG_PREFIX)
            ):
                filteredrefs.append(ref)
        filteredrefs.sort()

    # the choice of OrderedDict vs plain dict has no impact on stock
    # hg-git, but allows extensions to customize the order in which refs
    # are returned
    return collections.OrderedDict((r, refs[r]) for r in filteredrefs)
def _revsetutil(repo, subset, x, rtypes):
    """utility function to return a set of revs based on the rtypes"""
    args = revsetlang.getargs(x, 0, 1, _(b'only one argument accepted'))
    if args:
        kind, pattern, matcher = stringutil.stringmatcher(
            revsetlang.getstring(args[0], _(b'argument must be a string')))
    else:
        kind = pattern = None
        matcher = util.always

    nodes = set()
    cl = repo.changelog
    for rtype in rtypes:
        if rtype in repo.names:
            ns = repo.names[rtype]
            for name in ns.listnames(repo):
                if not matcher(name):
                    continue
                nodes.update(ns.nodes(repo, name))
    if kind == b'literal' and not nodes:
        raise error.RepoLookupError(
            _(b"remote name '%s' does not exist") % pattern)

    revs = (cl.rev(n) for n in nodes if cl.hasnode(n))
    return subset & smartset.baseset(revs)
示例#3
0
def parse_revnum(svnrepo, r):
    try:
        return int(r or 0)
    except ValueError:
        if isinstance(r, str) and r.lower() in ('head', 'tip'):
            return svnrepo.last_changed_rev
        else:
            raise error.RepoLookupError("unknown Subversion revision %r" % r)
示例#4
0
 def branchtip(self, branch, ignoremissing=False):
     try:
         return self.branchmap()[branch][0]
     except KeyError:
         if not ignoremissing:
             raise error.RepoLookupError(_("unknown branch '%s'") % branch)
         else:
             pass
示例#5
0
 def lookup(self, key):
     if key == 'null':
         return mercurial.node.nullid
     if key == 'tip':
         revid = self._controldir.open_branch().last_revision()
         return self._overlay.lookup_changeset_id_by_revid(revid)[0]
     if key == '.':
         raise NotImplementedError
     raise hgerrors.RepoLookupError("unknown revision '%s'" % key)
示例#6
0
def branch(repo, subset, x):
    # type: (gitrepository, abstractsmartset, Tuple) -> abstractsmartset
    """
    All changesets belonging to the given branch or the branches of the given
    changesets.

    Pattern matching is supported for `string`. See
    :hg:`help revisions.patterns`.
    """
    def getbranchrevs(r):
        return set(branches_with(repo._repo, r))

    # FIXME: look into sorting by branch name, to keep results stable
    branchrevs = set()
    revspec = False

    try:
        b = revset.getstring(x, '')
    except error.ParseError:
        # not a string, but another revspec, e.g. tip()
        revspec = True
    else:
        kind, pattern, matcher = stringutil.stringmatcher(b)
        branchmap = repo.branchmap()
        if kind == 'literal':
            # note: falls through to the revspec case if no branch with
            # this name exists and pattern kind is not specified explicitly
            if pattern in branchmap:
                branchrevs.add(branchmap[b][0])
            elif b.startswith('literal:'):
                raise error.RepoLookupError(
                    _("branch '%s' does not exist") % pattern)
            else:
                revspec = True
        else:
            branchrevs.update(r[0] for b, r in branchmap.items() if matcher(b))

    if revspec:
        # get all the branches in x
        s = revset.getset(repo, gitfullreposet(repo), x)
        for r in s:
            branchrevs.update(getbranchrevs(r))

    if not branchrevs:
        # FIXME: return empty set or subset?
        raise NotImplementedError

    brs = list(branchrevs)
    s = gitfullreposet(repo, heads=brs)
    return subset & s
示例#7
0
文件: revsets.py 项目: danchr/hg-git
def revset_gittag(repo, subset, x):
    """``gittag([name])``

    The specified Git tag by name, or all revisions tagged with Git if
    no name is given.

    Pattern matching is supported for `name`. See
    :hg:`help revisions.patterns`.

    """
    # mostly copied from tag() mercurial/revset.py

    # i18n: "tag" is a keyword
    args = revset.getargs(x, 0, 1, _(b"tag takes one or no arguments"))
    cl = repo.changelog
    git = repo.githandler

    if args:
        pattern = revset.getstring(
            args[0],
            # i18n: "tag" is a keyword
            _(b'the argument to tag must be a string'),
        )
        kind, pattern, matcher = stringutil.stringmatcher(pattern)
        if kind == b'literal':
            # avoid resolving all tags
            tn = git.tags.get(pattern, None)
            if tn is None:
                raise error.RepoLookupError(
                    _(b"git tag '%s' does not exist") % pattern)
            s = {repo[bin(tn)].rev()}
        else:
            s = {cl.rev(bin(n)) for t, n in git.tags.items() if matcher(t)}
    else:
        s = {cl.rev(bin(n)) for t, n in git.tags.items()}
    return subset & s
示例#8
0
    def __init__(self, repo, changeid='.'):
        # type: (gitrepository, Union[int, bytes]) -> None
        """changeid is a revision number, node, or tag"""
        super(gitchangectx, self).__init__(repo)

        try:
            if isinstance(changeid, pygit2.Oid):
                self._node = changeid
                self._rev = OidProxy(self._node)
                return
            if changeid in ['null', nullrev]:
                self._node = nullid
                self._rev = nullrev
                return
            if isinstance(changeid, OidProxy):
                self._node = changeid.id
                self._rev = changeid
                return
            # if hasattr(changeid, 'id'):
            #     self._node = changeid.id
            #     self._rev = self._node
            #     return
            # if changeid == 'tip':
            #     self._node = repo.changelog.tip()
            #     self._rev = repo.changelog.rev(self._node)
            #     return
            if (changeid == '.'
                    or repo.local() and changeid == repo.dirstate.p1()):
                # this is a hack to delay/avoid loading obsmarkers
                # when we know that '.' won't be hidden
                self._node = repo.dirstate.p1()
                self._rev = OidProxy(self._node)
                return
            # if len(changeid) == 20:
            #     try:
            #         self._node = changeid
            #         self._rev = repo.changelog.rev(changeid)
            #         return
            #     except error.FilteredLookupError:
            #         raise
            #     except LookupError:
            #         pass
        #
        #     try:
        #         r = int(changeid)
        #         if '%d' % r != changeid:
        #             raise ValueError
        #         l = len(repo.changelog)
        #         if r < 0:
        #             r += l
        #         if r < 0 or r >= l and r != wdirrev:
        #             raise ValueError
        #         self._rev = r
        #         self._node = repo.changelog.node(r)
        #         changectxdeprecwarn(repo)
        #         return
        #     except error.FilteredIndexError:
        #         raise
        #     except (ValueError, OverflowError, IndexError):
        #         pass
        #
        #     if len(changeid) == 40:
        #         try:
        #             self._node = bin(changeid)
        #             self._rev = repo.changelog.rev(self._node)
        #             return
        #         except error.FilteredLookupError:
        #             raise
        #         except (TypeError, LookupError):
        #             pass
        #
        #     # lookup bookmarks through the name interface
        #     try:
        #         self._node = repo.names.singlenode(repo, changeid)
        #         self._rev = repo.changelog.rev(self._node)
        #         changectxdeprecwarn(repo)
        #         return
        #     except KeyError:
        #         pass
        #
        #     self._node = scmutil.resolvehexnodeidprefix(repo, changeid)
        #     if self._node is not None:
        #         self._rev = repo.changelog.rev(self._node)
        #         changectxdeprecwarn(repo)
        #         return
        #
        #     # lookup failed
        #     # check if it might have come from damaged dirstate
        #     #
        #     # XXX we could avoid the unfiltered if we had a recognizable
        #     # exception for filtered changeset access
        #     if (repo.local()
        #         and changeid in repo.unfiltered().dirstate.parents()):
        #         msg = _("working directory has unknown parent '%s'!")
        #         raise error.Abort(msg % short(changeid))
        #     try:
        #         if len(changeid) == 20 and nonascii(changeid):
        #             changeid = hex(changeid)
        #     except TypeError:
        #         pass
        except (error.FilteredIndexError, error.FilteredLookupError):
            raise error.FilteredRepoLookupError(
                _("filtered revision '%s'") % changeid)
        except error.FilteredRepoLookupError:
            raise
        except IndexError:
            pass
        raise error.RepoLookupError(_("unknown revision '%s'") % changeid)
示例#9
0
 def expandname(self, bname):
     if bname == b'.':
         if self.active:
             return self.active
         raise error.RepoLookupError(_(b"no active bookmark"))
     return bname