Example #1
0
def revset_firefoxrelease(repo, subset, x):
    """``firefoxrelease([channel=], [platform=])

    Changesets that have Firefox releases built from them.

    Accepts the following named arguments:

    channel
       Which release channel to look at. e.g. ``nightly``. Multiple channels
       can be delimited by spaces.
    platform
       Which platform to limit builds to. e.g. ``win32``. Multiple platforms
       can be delimited by spaces.

    If multiple filters are requested filters are combined using logical AND.

    If no filters are specified, all revisions having a Firefox release are
    matched.
    """
    args = revset.getargsdict(x, 'firefoxrelease', 'channel platform')

    channels = set()

    if 'channel' in args:
        channels = set(
            revset.getstring(args['channel'],
                             _('channel requires a string')).split())

    platforms = set()

    if 'platform' in args:
        platforms = set(
            revset.getstring(args['platform'],
                             _('platform requires a '
                               'string')).split())

    db = db_for_repo(repo)
    if not db:
        repo.ui.warn(_('(warning: firefoxrelease() revset not available)\n'))
        return revset.baseset()

    def get_revs():
        for rev, builds in release_builds_by_revision(db, repo).iteritems():
            for build in builds:
                if channels and build.channel not in channels:
                    continue

                if platforms and build.platform not in platforms:
                    continue

                yield rev
                break

    return subset & revset.generatorset(get_revs())
Example #2
0
def _oldworkingcopyparent(repo, subset, x):
    """``oldworkingcopyparent([index])``
    previous working copy parent

    'index' is how many undoable commands you want to look back.  See 'hg undo'.
    """
    args = revset.getargsdict(x, 'oldoworkingcopyrevset', 'reverseindex')
    reverseindex = revsetlang.getinteger(args.get('reverseindex'),
                    _('index must be a positive interger'), 1)
    revs = _getoldworkingcopyparent(repo, reverseindex)
    return subset & smartset.baseset(revs)
Example #3
0
def underwayrevset(repo, subset, x):
    args = revset.getargsdict(x, 'underway', 'commitage headage')
    if 'commitage' not in args:
        args['commitage'] = None
    if 'headage' not in args:
        args['headage'] = None

    # We assume callers of this revset add a topographical sort on the
    # result. This means there is no benefit to making the revset lazy
    # since the topographical sort needs to consume all revs.
    #
    # With this in mind, we build up the set manually instead of constructing
    # a complex revset. This enables faster execution.

    # Mutable changesets (non-public) are the most important changesets
    # to return. ``not public()`` will also pull in obsolete changesets if
    # there is a non-obsolete changeset with obsolete ancestors. This is
    # why we exclude obsolete changesets from this query.
    rs = 'not public() and not obsolete()'
    rsargs = []
    if args['commitage']:
        rs += ' and date(%s)'
        rsargs.append(
            revsetlang.getstring(args['commitage'],
                                 _('commitage requires a string')))

    mutable = repo.revs(rs, *rsargs)
    relevant = revset.baseset(mutable)

    # Add parents of mutable changesets to provide context.
    relevant += repo.revs('parents(%ld)', mutable)

    # We also pull in (public) heads if they a) aren't closing a branch
    # b) are recent.
    rs = 'head() and not closed()'
    rsargs = []
    if args['headage']:
        rs += ' and date(%s)'
        rsargs.append(
            revsetlang.getstring(args['headage'],
                                 _('headage requires a string')))

    relevant += repo.revs(rs, *rsargs)

    # Add working directory parent.
    wdirrev = repo['.'].rev()
    if wdirrev != nullrev:
        relevant += revset.baseset(set([wdirrev]))

    return subset & relevant
Example #4
0
def _olddraft(repo, subset, x):
    """``olddraft([index])``
    previous draft commits

    'index' is how many undoable commands you want to look back
    an undoable command is one that changed draft heads, bookmarks
    and or working copy parent.  Note that olddraft uses an absolute index and
    so olddraft(1) represents the state after an hg undo -a and not an hg undo.
    Note: this revset may include hidden commits
    """
    args = revset.getargsdict(x, 'olddraftrevset', 'reverseindex')
    reverseindex = revsetlang.getinteger(args.get('reverseindex'),
                _('index must be a positive integer'), 1)
    revs = _getolddrafts(repo, reverseindex)
    return subset & smartset.baseset(revs)
Example #5
0
def _localbranch(repo, subset, x):
    """``_localbranch(changectx)``
    localbranch changesets

    Returns all commits within the same localbranch as the changeset(s). A local
    branch is all draft changesets that are connected, uninterupted by public
    changesets.  Any draft commit within a branch, or a public commit at the
    base of the branch, can be passed used to identify localbranches.
    """
    # executed on an filtered repo
    args = revset.getargsdict(x, 'branchrevset', 'changectx')
    revstring = revsetlang.getstring(args.get('changectx'),
                               _('localbranch argument must be a changectx'))
    revs = repo.revs(revstring)
    # we assume that there is only a single rev
    if repo[revs.first()].phase() == phases.public:
        querystring = revsetlang.formatspec('(children(%d) & draft())::',
                                            revs.first())
    else:
        querystring = revsetlang.formatspec('((::%ld) & draft())::', revs)
    return subset & smartset.baseset(repo.revs(querystring))
Example #6
0
def smartlogrevset(repo, subset, x):
    """``smartlog([master], [recentdays=N])``
    Changesets relevent to you.

    'master' is the head of the public branch.
    Unnamed heads will be hidden unless it's within 'recentdays'.
    """

    args = revset.getargsdict(x, 'smartlogrevset', 'master recentdays')
    if 'master' in args:
        masterstring = revsetlang.getstring(args['master'],
                                            _('master must be a string'))
    else:
        masterstring = ''

    recentdays = revsetlang.getinteger(args.get('recentdays'),
                                       _("recentdays should be int"), -1)

    revs = set()
    heads = set()

    rev = repo.changelog.rev
    ancestor = repo.changelog.ancestor
    node = repo.changelog.node
    parentrevs = repo.changelog.parentrevs

    books = bookmarks.bmstore(repo)
    ignore = re.compile(repo.ui.config('smartlog',
                                       'ignorebookmarks',
                                       '!'))
    for b in books:
        if not ignore.match(b):
            heads.add(rev(books[b]))

    # add 'interesting' remote bookmarks as well
    remotebooks = set()
    if util.safehasattr(repo, 'names') and 'remotebookmarks' in repo.names:
        ns = repo.names['remotebookmarks']
        remotebooks = set(ns.listnames(repo))
        for name in _reposnames(repo.ui):
            if name in remotebooks:
                heads.add(rev(ns.namemap(repo, name)[0]))

    heads.update(repo.revs('.'))

    global hiddenchanges
    headquery = 'head()'
    if remotebooks:
        # When we have remote bookmarks, only show draft heads, since public
        # heads should have a remote bookmark indicating them. This allows us
        # to force push server bookmarks to new locations, and not have the
        # commits clutter the user's smartlog.
        headquery = 'heads(draft())'

    allheads = set(repo.revs(headquery))
    if recentdays >= 0:
        recentquery = revsetlang.formatspec('%r & date(-%d)', headquery,
                                            recentdays)
        recentrevs = set(repo.revs(recentquery))
        hiddenchanges += len(allheads - heads) - len(recentrevs - heads)
        heads.update(recentrevs)
    else:
        heads.update(allheads)

    masterrevset = _masterrevset(repo.ui, repo, masterstring)
    masterrev = _masterrev(repo, masterrevset)

    if masterrev is None:
        masterrev = repo['tip'].rev()

    masternode = node(masterrev)

    # Find all draft ancestors and latest public ancestor of heads
    # that are not in master.
    # We don't want to draw all public commits because there can be too
    # many of them.
    # Don't use revsets, they are too slow
    for head in heads:
        anc = rev(ancestor(node(head), masternode))
        queue = [head]
        while queue:
            current = queue.pop(0)
            if current not in revs:
                revs.add(current)
                # stop as soon as we find public commit
                ispublic = repo[current].phase() == phases.public
                if current != anc and not ispublic:
                    parents = parentrevs(current)
                    for p in parents:
                        if p > anc:
                            queue.append(p)

    # add context: master, current commit, and the common ancestor
    revs.add(masterrev)

    return subset & revs
Example #7
0
def smartlogrevset(repo, subset, x):
    """``smartlog([master], [recentdays=N])``
    Changesets relevent to you.

    'master' is the head of the public branch.
    Unnamed heads will be hidden unless it's within 'recentdays'.
    """

    args = revset.getargsdict(x, 'smartlogrevset', 'master recentdays')
    if 'master' in args:
        masterstring = revsetlang.getstring(args['master'],
                                            _('master must be a string'))
    else:
        masterstring = ''

    recentdays = revsetlang.getinteger(args.get('recentdays'),
                                       _("recentdays should be int"), -1)

    revs = set()
    heads = set()

    rev = repo.changelog.rev
    branchinfo = repo.changelog.branchinfo
    ancestor = repo.changelog.ancestor
    node = repo.changelog.node
    parentrevs = repo.changelog.parentrevs

    books = bookmarks.bmstore(repo)
    ignore = re.compile(repo.ui.config('smartlog',
                                       'ignorebookmarks',
                                       '!'))
    for b in books:
        if not ignore.match(b):
            heads.add(rev(books[b]))

    # add 'interesting' remote bookmarks as well
    remotebooks = set()
    if util.safehasattr(repo, 'names') and 'remotebookmarks' in repo.names:
        ns = repo.names['remotebookmarks']
        remotebooks = set(ns.listnames(repo))
        for name in _reposnames(repo.ui):
            if name in remotebooks:
                heads.add(rev(ns.namemap(repo, name)[0]))

    heads.update(repo.revs('.'))

    global hiddenchanges
    headquery = 'head() & branch(.)'
    if remotebooks:
        # When we have remote bookmarks, only show draft heads, since public
        # heads should have a remote bookmark indicating them. This allows us
        # to force push server bookmarks to new locations, and not have the
        # commits clutter the user's smartlog.
        headquery = 'draft() &' + headquery

    allheads = set(repo.revs(headquery))
    if recentdays >= 0:
        recentquery = revsetlang.formatspec('%r & date(-%d)', headquery,
                                            recentdays)
        recentrevs = set(repo.revs(recentquery))
        hiddenchanges += len(allheads - heads) - len(recentrevs - heads)
        heads.update(recentrevs)
    else:
        heads.update(allheads)

    branches = set()
    for head in heads:
        branches.add(branchinfo(head)[0])

    masterrevset = _masterrevset(repo.ui, repo, masterstring)
    masterrev = _masterrev(repo, masterrevset)

    if masterrev is None:
        masterbranch = None
    else:
        masterbranch = branchinfo(masterrev)[0]

    for branch in branches:
        if branch != masterbranch:
            try:
                rs = 'first(reverse(branch("%s")) & public())' % branch
                branchmaster = repo.revs(rs).first()
                if branchmaster is None:
                    # local-only (draft) branch
                    rs = 'branch("%s")' % branch
                    branchmaster = repo.revs(rs).first()
            except Exception:
                branchmaster = repo.revs('tip').first()
        else:
            branchmaster = masterrev

        # Find all draft ancestors and latest public ancestor of heads
        # that are not in master.
        # We don't want to draw all public commits because there can be too
        # many of them.
        # Don't use revsets, they are too slow
        for head in heads:
            if branchinfo(head)[0] != branch:
                continue
            anc = rev(ancestor(node(head), node(branchmaster)))
            queue = [head]
            while queue:
                current = queue.pop(0)
                if current not in revs:
                    revs.add(current)
                    # stop as soon as we find public commit
                    ispublic = repo[current].phase() == phases.public
                    if current != anc and not ispublic:
                        parents = parentrevs(current)
                        for p in parents:
                            if p > anc:
                                queue.append(p)

        # add context: master, current commit, and the common ancestor
        revs.add(branchmaster)

        # get common branch ancestor
        if branch != masterbranch:
            anc = None
            for r in revs:
                if branchinfo(r)[0] != branch:
                    continue
                if anc is None:
                    anc = r
                else:
                    anc = rev(ancestor(node(anc), node(r)))
            if anc:
                revs.add(anc)

    return subset & revs