def revset_automationrelevant(repo, subset, x):
    """``automationrelevant(set)``

    Changesets relevant to scheduling in automation.

    Given a revset that evaluates to a single revision, will return that
    revision and any ancestors that are part of the same push unioned with
    non-public ancestors.
    """
    s = revset.getset(repo, revset.fullreposet(repo), x)
    if len(s) > 1:
        raise error.Abort(b'can only evaluate single changeset')

    ctx = repo[s.first()]
    revs = {ctx.rev()}

    # The pushlog is used to get revisions part of the same push as
    # the requested revision.
    pushlog = getattr(repo, 'pushlog', None)
    if pushlog:
        push = repo.pushlog.pushfromchangeset(ctx)
        for n in push.nodes:
            pctx = repo[n]
            if pctx.rev() <= ctx.rev():
                revs.add(pctx.rev())

    # Union with non-public ancestors if configured. By default, we only
    # consider changesets from the push. However, on special repositories
    # (namely Try), we want changesets from previous pushes to come into
    # play too.
    if repo.ui.configbool(b'hgmo', b'automationrelevantdraftancestors', False):
        for rev in repo.revs(b'::%d & not public()', ctx.rev()):
            revs.add(rev)

    return subset & revset.baseset(revs)
def revset_automationrelevant(repo, subset, x):
    """``automationrelevant(set)``

    Changesets relevant to scheduling in automation.

    Given a revset that evaluates to a single revision, will return that
    revision and any ancestors that are part of the same push unioned with
    non-public ancestors.
    """
    s = revset.getset(repo, revset.fullreposet(repo), x)
    if len(s) > 1:
        raise util.Abort('can only evaluate single changeset')

    ctx = repo[s.first()]
    revs = set([ctx.rev()])

    # The pushlog is used to get revisions part of the same push as
    # the requested revision.
    pushlog = getattr(repo, 'pushlog', None)
    if pushlog:
        pushinfo = repo.pushlog.pushfromchangeset(ctx)
        for n in pushinfo[3]:
            pctx = repo[n]
            if pctx.rev() <= ctx.rev():
                revs.add(pctx.rev())

    # Union with non-public ancestors.
    for rev in repo.revs('::%d & not public()', ctx.rev()):
        revs.add(rev)

    return subset & revset.baseset(revs)
Ejemplo n.º 3
0
def revsettransplanted(repo, subset, x):
    """Transplanted changesets in set, or all transplanted changesets."""
    if x:
        s = revset.getset(repo, subset, x)
    else:
        s = subset
    return smartset.baseset(
        [r for r in s if repo[r].extra().get(b'transplant_source')])
Ejemplo n.º 4
0
def revsettransplanted(repo, subset, x):
    """``transplanted([set])``
    Transplanted changesets in set, or all transplanted changesets.
    """
    if x:
        s = revset.getset(repo, subset, x)
    else:
        s = subset
    return [r for r in s if repo[r].extra().get('transplant_source')]
Ejemplo n.º 5
0
def revsettransplanted(repo, subset, x):
    """``transplanted([set])``
    Transplanted changesets in set, or all transplanted changesets.
    """
    if x:
      s = revset.getset(repo, subset, x)
    else:
      s = subset
    return [r for r in s if repo[r].extra().get('transplant_source')]
Ejemplo n.º 6
0
def _destrestack(repo, subset, x):
    """restack destination for given single source revision"""
    unfi = repo.unfiltered()
    obsoleted = unfi.revs('obsolete()')
    getparents = unfi.changelog.parentrevs
    getphase = unfi._phasecache.phase
    nodemap = unfi.changelog.nodemap

    src = revset.getset(repo, subset, x).first()

    # Empty src or already obsoleted - Do not return a destination
    if not src or src in obsoleted:
        return smartset.baseset()

    # Find the obsoleted "base" by checking source's parent recursively
    base = src
    while base not in obsoleted:
        base = getparents(base)[0]
        # When encountering a public revision which cannot be obsoleted, stop
        # the search early and return no destination. Do the same for nullrev.
        if getphase(repo, base) == phases.public or base == nullrev:
            return smartset.baseset()

    # Find successors for given base
    # NOTE: Ideally we can use obsutil.successorssets to detect divergence
    # case. However it does not support cycles (unamend) well. So we use
    # allsuccessors and pick non-obsoleted successors manually as a workaround.
    basenode = repo[base].node()
    succnodes = [n for n in obsutil.allsuccessors(repo.obsstore, [basenode])
                 if (n != basenode and n in nodemap
                     and nodemap[n] not in obsoleted)]

    # In case of a split, only keep its heads
    succrevs = list(unfi.revs('heads(%ln)', succnodes))

    if len(succrevs) == 0:
        # Prune - Find the first non-obsoleted ancestor
        while base in obsoleted:
            base = getparents(base)[0]
            if base == nullrev:
                # Root node is pruned. The new base (destination) is the
                # virtual nullrev.
                return smartset.baseset([nullrev])
        return smartset.baseset([base])
    elif len(succrevs) == 1:
        # Unique visible successor case - A valid destination
        return smartset.baseset([succrevs[0]])
    else:
        # Multiple visible successors - Choose the one with a greater revision
        # number. This is to be compatible with restack old behavior. We might
        # want to revisit it when we introduce the divergence concept to users.
        return smartset.baseset([max(succrevs)])
Ejemplo n.º 7
0
def revsettransplanted(repo, subset, x):
    """``transplanted(set)``
    Transplanted changesets in set.
    """
    if x:
      s = revset.getset(repo, subset, x)
    else:
      s = subset
    cs = set()
    for r in xrange(0, len(repo)):
      if repo[r].extra().get('transplant_source'):
        cs.add(r)
    return [r for r in s if r in cs]
Ejemplo n.º 8
0
def revsettransplanted(repo, subset, x):
    """``transplanted(set)``
    Transplanted changesets in set.
    """
    if x:
        s = revset.getset(repo, subset, x)
    else:
        s = subset
    cs = set()
    for r in xrange(0, len(repo)):
        if repo[r].extra().get('transplant_source'):
            cs.add(r)
    return [r for r in s if r in cs]
Ejemplo n.º 9
0
def revset_pushrev(repo, subset, x):
    """Changesets that were part of the same push as the specified changeset(s)."""
    l = revset.getset(repo, subset, x)

    # This isn't the most optimal implementation, especially if the input
    # set is large. But it gets the job done.
    revs = set()
    for rev in l:
        push = repo.pushlog.pushfromchangeset(repo[rev])
        if push:
            for node in push.nodes:
                revs.add(repo[node].rev())

    return subset.filter(revs.__contains__)
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def _calculateset(repo, subset, x, f):
    """f is a function that converts input nodes to output nodes

    repo, subset, x are typical revsetpredicate parameters.

    This function takes care of converting between revs/nodes, and filtering.
    """
    revs = revset.getset(repo, revset.fullreposet(repo), x)
    cl = repo.unfiltered().changelog
    torev = cl.rev
    tonode = cl.node
    nodemap = cl.nodemap
    resultrevs = set(torev(n)
                     for n in f(tonode(r) for r in revs)
                     if n in nodemap)
    s = smartset.baseset(resultrevs - set(revs) - repo.changelog.filteredrevs)
    s.sort()
    return subset & s