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)
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)
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
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)
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
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
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)
def expandname(self, bname): if bname == b'.': if self.active: return self.active raise error.RepoLookupError(_(b"no active bookmark")) return bname