Пример #1
0
def getlogrevs(repo, pats, opts):
    """Return (revs, expr, filematcher) where revs is a list of
    revision numbers, expr is a revset string built from log options
    and file patterns or None, and used to filter 'revs'. If --stat or
    --patch are not passed filematcher is None. Otherwise it is a
    callable taking a revision number and returning a match objects
    filtering the files to be detailed when displaying the revision.
    """
    if not len(repo):
        return [], None, None
    # Default --rev value depends on --follow but --follow behaviour
    # depends on revisions resolved from --rev...
    follow = opts.get('follow') or opts.get('follow_first')
    if opts.get('rev'):
        revs = scmutil.revrange(repo, opts['rev'])
    else:
        if follow and len(repo) > 0:
            revs = scmutil.revrange(repo, ['.:0'])
        else:
            revs = range(len(repo) - 1, -1, -1)
    if not revs:
        return [], None, None
    expr, filematcher = _makelogrevset(repo, pats, opts, revs)
    if expr:
        # Evaluate revisions in changelog order for performance
        # reasons but preserve the original sequence order in the
        # filtered result.
        matched = set(revset.match(repo.ui, expr)(repo, sorted(revs)))
        revs = [r for r in revs if r in matched]
    if not opts.get('hidden'):
        # --hidden is still experimental and not worth a dedicated revset
        # yet. Fortunately, filtering revision number is fast.
        revs = [r for r in revs if r not in repo.changelog.hiddenrevs]
    return revs, expr, filematcher
Пример #2
0
def getrevstofix(ui, repo, opts):
    """Returns the set of revision numbers that should be fixed"""
    if opts[b'all']:
        revs = repo.revs(b'(not public() and not obsolete()) or wdir()')
    elif opts[b'source']:
        source_revs = scmutil.revrange(repo, opts[b'source'])
        revs = set(repo.revs(b'(%ld::) - obsolete()', source_revs))
        if wdirrev in source_revs:
            # `wdir()::` is currently empty, so manually add wdir
            revs.add(wdirrev)
        if repo[b'.'].rev() in revs:
            revs.add(wdirrev)
    else:
        revs = set(scmutil.revrange(repo, opts[b'rev']))
        if opts.get(b'working_dir'):
            revs.add(wdirrev)
        for rev in revs:
            checkfixablectx(ui, repo, repo[rev])
    # Allow fixing only wdir() even if there's an unfinished operation
    if not (len(revs) == 1 and wdirrev in revs):
        cmdutil.checkunfinished(repo)
        rewriteutil.precheck(repo, revs, b'fix')
    if wdirrev in revs and list(
        mergestatemod.mergestate.read(repo).unresolved()
    ):
        raise error.Abort(b'unresolved conflicts', hint=b"use 'hg resolve'")
    if not revs:
        raise error.Abort(
            b'no changesets specified', hint=b'use --source or --working-dir'
        )
    return revs
Пример #3
0
def fastexport(ui, repo, *revs, **opts):
    """export repository as git fast-import stream

    This command lets you dump a repository as a human-readable text stream.
    It can be piped into corresponding import routines like "git fast-import".
    Incremental dumps can be created by using marks files.
    """
    opts = pycompat.byteskwargs(opts)

    revs += tuple(opts.get(b"rev", []))
    if not revs:
        revs = scmutil.revrange(repo, [b":"])
    else:
        revs = scmutil.revrange(repo, revs)
    if not revs:
        raise error.Abort(_(b"no revisions matched"))
    authorfile = opts.get(b"authormap")
    if authorfile:
        authormap = convcmd.readauthormap(ui, authorfile)
    else:
        authormap = {}

    import_marks = opts.get(b"import_marks")
    marks = {}
    if import_marks:
        with open(import_marks, "rb") as import_marks_file:
            for line in import_marks_file:
                line = line.strip()
                if not isrev.match(line) or line in marks:
                    raise error.Abort(_(b"Corrupted marks file"))
                marks[line] = len(marks) + 1

    revs.sort()
    with ui.makeprogress(_(b"exporting"),
                         unit=_(b"revisions"),
                         total=len(revs)) as progress:
        for rev in revs:
            export_commit(ui, repo, rev, marks, authormap)
            progress.increment()

    export_marks = opts.get(b"export_marks")
    if export_marks:
        with open(export_marks, "wb") as export_marks_file:
            output_marks = [None] * len(marks)
            for k, v in marks.items():
                output_marks[v - 1] = k
            for k in output_marks:
                export_marks_file.write(k + b"\n")
Пример #4
0
def pull(orig, ui, repo, *pats, **opts):
    result = orig(ui, repo, *pats, **opts)

    if shallowrepo.requirement in repo.requirements:
        # prefetch if it's configured
        prefetchrevset = ui.config('remotefilelog', 'pullprefetch', None)
        bgrepack = repo.ui.configbool('remotefilelog',
                                      'backgroundrepack', False)
        bgprefetch = repo.ui.configbool('remotefilelog',
                                        'backgroundprefetch', False)

        if prefetchrevset:
            ui.status(_("prefetching file contents\n"))
            revs = scmutil.revrange(repo, [prefetchrevset])
            base = repo['.'].rev()
            if bgprefetch:
                repo.backgroundprefetch(prefetchrevset, repack=bgrepack)
            else:
                repo.prefetch(revs, base=base)
                if bgrepack:
                    repackmod.backgroundrepack(repo, incremental=True)
        elif bgrepack:
            repackmod.backgroundrepack(repo, incremental=True)

    return result
Пример #5
0
def keepset(repo, keyfn, lastkeepkeys=None):
    """Computes a keepset which is not garbage collected.
    'keyfn' is a function that maps filename, node to a unique key.
    'lastkeepkeys' is an optional argument and if provided the keepset
    function updates lastkeepkeys with more keys and returns the result.
    """
    if not lastkeepkeys:
        keepkeys = set()
    else:
        keepkeys = lastkeepkeys

    # We want to keep:
    # 1. Working copy parent
    # 2. Draft commits
    # 3. Parents of draft commits
    # 4. Pullprefetch and bgprefetchrevs revsets if specified
    revs = ['.', 'draft()', 'parents(draft())']
    prefetchrevs = repo.ui.config('remotefilelog', 'pullprefetch', None)
    if prefetchrevs:
        revs.append('(%s)' % prefetchrevs)
    prefetchrevs = repo.ui.config('remotefilelog', 'bgprefetchrevs', None)
    if prefetchrevs:
        revs.append('(%s)' % prefetchrevs)
    revs = '+'.join(revs)

    revs = ['sort((%s), "topo")' % revs]
    keep = scmutil.revrange(repo, revs)

    processed = set()
    lastmanifest = None

    # process the commits in toposorted order starting from the oldest
    for r in reversed(keep._list):
        if repo[r].p1().rev() in processed:
            # if the direct parent has already been processed
            # then we only need to process the delta
            m = repo[r].manifestctx().readdelta()
        else:
            # otherwise take the manifest and diff it
            # with the previous manifest if one exists
            if lastmanifest:
                m = repo[r].manifest().diff(lastmanifest)
            else:
                m = repo[r].manifest()
        lastmanifest = repo[r].manifest()
        processed.add(r)

        # populate keepkeys with keys from the current manifest
        if type(m) is dict:
            # m is a result of diff of two manifests and is a dictionary that
            # maps filename to ((newnode, newflag), (oldnode, oldflag)) tuple
            for filename, diff in m.iteritems():
                if diff[0][0] is not None:
                    keepkeys.add(keyfn(filename, diff[0][0]))
        else:
            # m is a manifest object
            for filename, filenode in m.iteritems():
                keepkeys.add(keyfn(filename, filenode))

    return keepkeys
Пример #6
0
def _revive(repo, rev):
    """Brings the given rev back into the repository. Finding it in backup
    bundles if necessary.
    """
    unfi = repo.unfiltered()
    try:
        ctx = unfi[rev]
    except error.RepoLookupError:
        # It could either be a revset or a stripped commit.
        pass
    else:
        if ctx.obsolete():
            try:
                inhibit = extensions.find('inhibit')
            except KeyError:
                raise error.Abort(_('cannot revive %s - inhibit extension '
                                    'is not enabled') % ctx)
            else:
                torevive = unfi.set('::%d & obsolete()', ctx.rev())
                inhibit.revive(torevive, operation='reset')

    try:
        revs = scmutil.revrange(repo, [rev])
        if len(revs) > 1:
            raise error.Abort(_('exactly one revision must be specified'))
        if len(revs) == 1:
            return repo[revs.first()]
    except error.RepoLookupError:
        revs = []

    return _pullbundle(repo, rev)
Пример #7
0
def lfpull(ui, repo, source="default", **opts):
    """pull largefiles for the specified revisions from the specified source

    Pull largefiles that are referenced from local changesets but missing
    locally, pulling from a remote repository to the local cache.

    If SOURCE is omitted, the 'default' path will be used.
    See :hg:`help urls` for more information.

    .. container:: verbose

      Some examples:

      - pull largefiles for all branch heads::

          hg lfpull -r "head() and not closed()"

      - pull largefiles on the default branch::

          hg lfpull -r "branch(default)"
    """
    repo.lfpullsource = source

    revs = opts.get('rev', [])
    if not revs:
        raise util.Abort(_('no revisions specified'))
    revs = scmutil.revrange(repo, revs)

    numcached = 0
    for rev in revs:
        ui.note(_('pulling largefiles for revision %s\n') % rev)
        (cached, missing) = cachelfiles(ui, repo, rev)
        numcached += len(cached)
    ui.status(_("%d largefiles cached\n") % numcached)
Пример #8
0
def check_hook(ui, repo, hooktype, node, **kwargs):
    '''blocks commits/changesets containing tabs or trailing whitespace'''

    if hooktype == 'pretxncommit':
        ui.note(
            'checkfiles: checking commit for tabs or trailing whitespace...\n')
        cf = CheckFiles(ui, repo, repo.changectx(node))
        return cf.check()

    elif hooktype == 'pretxnchangegroup':
        try:
            from mercurial.scmutil import revrange
        except ImportError:
            # 1.8 and earlier
            from mercurial.cmdutil import revrange

        ui.note(
            'checkfiles: checking incoming changes for tabs or trailing whitespace...\n'
        )
        cf = CheckFiles(ui, repo, repo[None])
        fail = False

        for rev in revrange(repo, ['%s::' % node]):
            cf.set_changectx(repo.changectx(rev))
            cf.files = cf.ctx.files()
            fail = cf.check() or fail

        return fail
    else:
        from mercurial import util
        raise util.Abort(
            _('checkfiles: check_hook installed as unsupported hooktype: %s') %
            hooktype)
def lfpull(ui, repo, source="default", **opts):
    """pull largefiles for the specified revisions from the specified source

    Pull largefiles that are referenced from local changesets but missing
    locally, pulling from a remote repository to the local cache.

    If SOURCE is omitted, the 'default' path will be used.
    See :hg:`help urls` for more information.

    .. container:: verbose

      Some examples:

      - pull largefiles for all branch heads::

          hg lfpull -r "head() and not closed()"

      - pull largefiles on the default branch::

          hg lfpull -r "branch(default)"
    """
    repo.lfpullsource = source

    revs = opts.get(r'rev', [])
    if not revs:
        raise error.Abort(_('no revisions specified'))
    revs = scmutil.revrange(repo, revs)

    numcached = 0
    for rev in revs:
        ui.note(_('pulling largefiles for revision %s\n') % rev)
        (cached, missing) = cachelfiles(ui, repo, rev)
        numcached += len(cached)
    ui.status(_("%d largefiles cached\n") % numcached)
Пример #10
0
def fastmanifesttocache(repo, subset, x):
    """Revset of the interesting revisions to cache. This returns:
    - Drafts
    - Revisions with a bookmarks
    - Revisions with some selected remote bookmarks (master, stable ...)
    - Their parents (to make diff -c faster)
    - TODO The base of potential rebase operations
    - Filtering all of the above to only include recent changes
    """

    # Add relevant remotenames to the list of interesting revs
    revs = _relevantremonamesrevs(repo)

    # Add all the other relevant revs
    query = "(not public() & not hidden()) + bookmark()"
    cutoff = repo.ui.configint("fastmanifest", "cachecutoffdays", 60)
    if cutoff == -1: # no cutoff
        datelimit = ""
    else:
        datelimit = "and date(-%d)" % cutoff

    revs.update(scmutil.revrange(repo,["(%s + parents(%s)) %s"
                % (query, query, datelimit)]))

    metricscollector.get().recordsample("revsetsize", size=len(revs))
    return subset & revs
Пример #11
0
def keepset(repo, keyfn, lastkeepkeys=None):
    """Computes a keepset which is not garbage collected.
    'keyfn' is a function that maps filename, node to a unique key.
    'lastkeepkeys' is an optional argument and if provided the keepset
    function updates lastkeepkeys with more keys and returns the result.
    """
    if not lastkeepkeys:
        keepkeys = set()
    else:
        keepkeys = lastkeepkeys

    # We want to keep:
    # 1. Working copy parent
    # 2. Draft commits
    # 3. Parents of draft commits
    # 4. Pullprefetch and bgprefetchrevs revsets if specified
    revs = ['.', 'draft()', 'parents(draft())']
    prefetchrevs = repo.ui.config('remotefilelog', 'pullprefetch', None)
    if prefetchrevs:
        revs.append('(%s)' % prefetchrevs)
    prefetchrevs = repo.ui.config('remotefilelog', 'bgprefetchrevs', None)
    if prefetchrevs:
        revs.append('(%s)' % prefetchrevs)
    revs = '+'.join(revs)

    revs = ['sort((%s), "topo")' % revs]
    keep = scmutil.revrange(repo, revs)

    processed = set()
    lastmanifest = None

    # process the commits in toposorted order starting from the oldest
    for r in reversed(keep._list):
        if repo[r].p1().rev() in processed:
            # if the direct parent has already been processed
            # then we only need to process the delta
            m = repo[r].manifestctx().readdelta()
        else:
            # otherwise take the manifest and diff it
            # with the previous manifest if one exists
            if lastmanifest:
                m = repo[r].manifest().diff(lastmanifest)
            else:
                m = repo[r].manifest()
        lastmanifest = repo[r].manifest()
        processed.add(r)

        # populate keepkeys with keys from the current manifest
        if type(m) is dict:
            # m is a result of diff of two manifests and is a dictionary that
            # maps filename to ((newnode, newflag), (oldnode, oldflag)) tuple
            for filename, diff in m.iteritems():
                if diff[0][0] is not None:
                    keepkeys.add(keyfn(filename, diff[0][0]))
        else:
            # m is a manifest object
            for filename, filenode in m.iteritems():
                keepkeys.add(keyfn(filename, filenode))

    return keepkeys
Пример #12
0
def getbasectxs(repo, opts, revstofix):
    """Returns a map of the base contexts for each revision

    The base contexts determine which lines are considered modified when we
    attempt to fix just the modified lines in a file. It also determines which
    files we attempt to fix, so it is important to compute this even when
    --whole is used.
    """
    # The --base flag overrides the usual logic, and we give every revision
    # exactly the set of baserevs that the user specified.
    if opts.get(b'base'):
        baserevs = set(scmutil.revrange(repo, opts.get(b'base')))
        if not baserevs:
            baserevs = {nullrev}
        basectxs = {repo[rev] for rev in baserevs}
        return {rev: basectxs for rev in revstofix}

    # Proceed in topological order so that we can easily determine each
    # revision's baserevs by looking at its parents and their baserevs.
    basectxs = collections.defaultdict(set)
    for rev in sorted(revstofix):
        ctx = repo[rev]
        for pctx in ctx.parents():
            if pctx.rev() in basectxs:
                basectxs[rev].update(basectxs[pctx.rev()])
            else:
                basectxs[rev].add(pctx)
    return basectxs
Пример #13
0
def overlay(ui, repo, sourceurl, revs=None, dest=None, into=None,
            noncontiguous=False, notify=None):
    """Integrate contents of another repository.

    This command essentially replays changesets from another repository into
    this one. Unlike a simple pull + rebase, the files from the remote
    repository are "overlayed" or unioned with the contents of the destination
    repository.

    The functionality of this command is nearly identical to what ``hg
    transplant`` provides. However, the internal mechanism varies
    substantially.

    There are currently several restrictions to what can be imported:

    * The imported changesets must be in a single DAG head
    * The imported changesets (as evaluated by ``REVS``) must be a contiguous
      DAG range (Unless --noncontiguous is passed).
    * Importing merges is not supported.
    * The state of the files in the destination directory/changeset must
      exactly match the last imported changeset.

    That last point is important: it means that this command can effectively
    only be used for unidirectional syncing. In other words, the source
    repository must be the single source of all changes to the destination
    directory.

    The restriction of states being identical is to ensure that changesets
    in the source and destination are as similar as possible. For example,
    if the file content in the destination did not match the source, then
    the ``hg diff`` output for the next overlayed changeset would differ from
    the source.

    This command supports sending human readable notifications in the event
    that an overlay failed. Set --notify to an command that handles delivery
    of these errors. The message will be piped to the command via STDIN.
    """
    # We could potentially support this later.
    if not into:
        raise error.Abort(_('--into must be specified'))

    if not revs:
        revs = 'all()'

    sourcerepo = _mirrorrepo(ui, repo, sourceurl)
    sourcerevs = scmutil.revrange(sourcerepo, [revs])

    if not sourcerevs:
        raise error.Abort(_('unable to determine source revisions'))

    if dest:
        destctx = scmutil.revsymbol(repo, dest)
    else:
        destctx = scmutil.revsymbol(repo, 'tip')

    # Backdoor for testing to force static URL.
    sourceurl = ui.config('overlay', 'sourceurl', sourceurl)

    _dooverlay(sourcerepo, sourceurl, sourcerevs, repo, destctx, into,
               noncontiguous, notify)
Пример #14
0
def _summarise_changed(summary, repo_name, repo, last_ctx, prefix, files):
    overlaid_ctx = None
    all_ctxs = []
    matching_ctxs = []

    # Find revisions newer than the last overlaid.
    dest_revs = scmutil.revrange(
        repo, ['%s:: and file("path:%s")' % (last_ctx.hex(), prefix)])
    for rev in dest_revs:
        ctx = repo[rev]

        if not overlaid_ctx:
            overlaid_ctx = ctx
            continue

        all_ctxs.append(ctx)

        # Report on revisions that touch problematic files.
        if files and (set(ctx.files()) & files):
            matching_ctxs.append(ctx)

    # No revisions to report.
    if not all_ctxs:
        return

    summary.extend(['', _('%s Repository:') % repo_name,
                    '', _('Last overlaid revision:')])
    summary.extend(_ctx_summary(overlaid_ctx))
    summary.extend(['', _('Revisions that require investigation:')])

    # If we didn't find any revisions that match the problematic files report
    # on all revisions instead.
    for ctx in matching_ctxs if matching_ctxs else all_ctxs:
        summary.extend(_ctx_summary(ctx))
Пример #15
0
def graphlog(ui, repo, *pats, **opts):
    """show revision history alongside an ASCII revision graph

    Print a revision history alongside a revision graph drawn with
    ASCII characters.

    Nodes printed as an @ character are parents of the working
    directory.
    """

    revs, expr, filematcher = getlogrevs(repo, pats, opts)
    revs = sorted(revs, reverse=1)
    limit = cmdutil.loglimit(opts)
    if limit is not None:
        revs = revs[:limit]
    revdag = graphmod.dagwalker(repo, revs)

    getrenamed = None
    if opts.get('copies'):
        endrev = None
        if opts.get('rev'):
            endrev = max(scmutil.revrange(repo, opts.get('rev'))) + 1
        getrenamed = templatekw.getrenamedfn(repo, endrev=endrev)
    displayer = show_changeset(ui, repo, opts, buffered=True)
    showparents = [ctx.node() for ctx in repo[None].parents()]
    generate(ui, revdag, displayer, showparents, asciiedges, getrenamed,
             filematcher)
Пример #16
0
    def delete(self, repo, patches, opts):
        if not patches and not opts.get('rev'):
            raise util.Abort(_('qdelete requires at least one revision or '
                               'patch name'))

        realpatches = []
        for patch in patches:
            patch = self.lookup(patch, strict=True)
            info = self.isapplied(patch)
            if info:
                raise util.Abort(_("cannot delete applied patch %s") % patch)
            if patch not in self.series:
                raise util.Abort(_("patch %s not in series file") % patch)
            if patch not in realpatches:
                realpatches.append(patch)

        numrevs = 0
        if opts.get('rev'):
            if not self.applied:
                raise util.Abort(_('no patches applied'))
            revs = scmutil.revrange(repo, opts.get('rev'))
            if len(revs) > 1 and revs[0] > revs[1]:
                revs.reverse()
            revpatches = self._revpatches(repo, revs)
            realpatches += revpatches
            numrevs = len(revpatches)

        self._cleanup(realpatches, numrevs, opts.get('keep'))
Пример #17
0
def check_hook(ui, repo, hooktype, **kwargs):
    """blocks commits/changesets containing tabs or trailing whitespace"""

    if hooktype == 'precommit':
        ui.note('checkfiles: checking for tabs and/or trailing whitespace ' \
                'in changed files...\n')

        cf = CheckFiles(ui, repo, repo[None])
        return cf.check()

    if hooktype == 'pretxncommit':
        ui.note('checkfiles: checking commit for tabs or trailing ' \
                'whitespace...\n')

        node = kwargs['node']
        cf = CheckFiles(ui, repo, repo.changectx(node))
        return cf.check()

    elif hooktype == 'pretxnchangegroup':
        ui.note('checkfiles: checking incoming changes for tabs or trailing ' \
                'whitespace...\n')
        cf = CheckFiles(ui, repo, repo[None])
        fail = False
        node = kwargs['node']

        for rev in revrange(repo, ['%s::' % node]):
            cf.set_changectx(repo.changectx(rev))
            cf.files = cf.ctx.files()
            fail = cf.check() or fail

        return fail
    else:
        raise util.Abort(_('checkfiles: check_hook installed as unsupported ' \
                           'hooktype: %s') % hooktype)
Пример #18
0
def squash(ui, repo, **opts):
    """Simple extension that squashes multiple revisions into a single one"""

    revrange = scmutil.revrange(repo, opts["rev"])
    if not revrange:
        raise util.Abort(_("Please specify a revision"))

    start = revrange[0]
    end = revrange[-1]

    revs = find_revisions(start, end, repo)

    if not revs:
        raise util.Abort(_("The revision %s is not an ancestor of %s\n") % (start, end))
    elif len(revs) == 1:
        raise util.Abort(_("Please specify a start and an end revision"))

    verify_user(ui, repo, revs)

    no_children(ui, repo, end)

    has_parent(ui, repo, start)

    verify_pending_commits(repo)

    squash_revisions(ui, repo, revs, start, end)

    for r in revs:
        ui.status("rev: %s, owner: %s\n" % (repo[r], ui.username()))
Пример #19
0
def check_hook(ui, repo, hooktype, node, **kwargs):
    '''blocks commits/changesets containing tabs or trailing whitespace'''

    if hooktype == 'pretxncommit':
        ui.note('checkfiles: checking commit for tabs or trailing whitespace...\n')
        cf = CheckFiles(ui, repo, repo.changectx(node))
        return cf.check()

    elif hooktype == 'pretxnchangegroup':
        try:
            from mercurial.scmutil import revrange
        except ImportError:
            # 1.8 and earlier
            from mercurial.cmdutil import revrange

        ui.note('checkfiles: checking incoming changes for tabs or trailing whitespace...\n')
        cf = CheckFiles(ui, repo, repo[None])
        fail = False

        for rev in revrange(repo, ['%s::' % node]):
            cf.set_changectx(repo.changectx(rev))
            cf.files = cf.ctx.files()
            fail = cf.check() or fail

        return fail
    else:
        from mercurial import util
        raise util.Abort(_('checkfiles: check_hook installed as unsupported hooktype: %s') %
                           hooktype)
Пример #20
0
def get_verification_stats(ui, repo, *revrange, **opts):
    """verify manifest signatures

    Verify repository heads, the revision range specified or all
    changesets. Each verification's result code is one of:

    - 0 if all changesets had valid signatures
    - 1 if there were a changeset without a signature
    - 2 if an exception was raised while verifying a changeset
    - 3 if there were a changeset with a bad signature

    The return value is the stats of all verification results.

    """
    if opts.get('only_heads'):
        revs = repo.heads()
    elif not revrange:
        revs = xrange(len(repo))
    else:
        revs = scmutil.revrange(repo, revrange)

    stats = dict.fromkeys(range(4), 0)
    user_aliases = CONFIG.get('useraliases', {})
    for rev in revs:
        retcode = 0
        ctx = repo[rev]
        h = ctxhash(ctx)
        extra = ctx.extra()
        sig = extra.get('signature')
        if not sig:
            msg = _("** no signature")
            retcode = 1
        else:
            ui.debug(_("signature: %s\n") % sig)
            try:
                scheme, sig = sig.split(":", 1)
                verifyfunc = sigschemes[scheme][1]
                result = verifyfunc(hex(h), sig, quiet=True)
                if result['success']:
                    msg = _("good %s signature") % scheme
                    identity = result.get('identity')
                    if identity:
                        msg += _(' by %s') % identity
                        user = ctx.user()
                        if identity not in user_aliases.get(user, (user, )):
                            msg += _(' but committed by %s') % user
                    details = result.get('details')
                    if details:
                        ui.note(details + '\n')
                else:
                    msg = _("** bad %s signature on %s") % (scheme, short(h))
                    retcode = 3
            except Exception, e:
                msg = _("** exception while verifying %s signature: %s") \
                    % (scheme, e)
                retcode = 2
        stats[retcode] += 1
        if not opts.get('quiet'):
            ui.write("%d:%s: %s\n" % (ctx.rev(), ctx, msg))
Пример #21
0
def critic(ui, repo, rev='.', entire=False, **opts):
    """Perform a critique of changeset(s).

    This will perform static analysis on changeset(s) and report any issues
    found.
    """
    for r in scmutil.revrange(repo, [rev]):
        critique(ui, repo, node=r, entire=entire, **opts)
Пример #22
0
def critic(ui, repo, rev='.', entire=False, **opts):
    """Perform a critique of changeset(s).

    This will perform static analysis on changeset(s) and report any issues
    found.
    """
    for r in scmutil.revrange(repo, [rev]):
        critique(ui, repo, node=r, entire=entire, **opts)
Пример #23
0
def get_revs(repo, rev_opt):
    if rev_opt:
        revs = scmutil.revrange(repo, rev_opt)
        if len(revs) == 0:
            return (nullrev, nullrev)
        return (max(revs), min(revs))
    else:
        return (len(repo) - 1, 0)
Пример #24
0
def get_hgtags_from_heads(ui, repo, rev):
    from mercurial import scmutil
    heads = scmutil.revrange(repo,['heads(%d::)' % (rev)])
    head_hgtags = dict()
    for h in heads:
        if '.hgtags' in repo[h]:
            hgtags = repo[h]['.hgtags'].data()
            head_hgtags[hex(repo[h].node())] = hgtags
    return head_hgtags
Пример #25
0
def obsoleteinfo(repo, hgcmd):
    """Return obsolescence markers that are relevant to smartlog revset"""
    unfi = repo.unfiltered()
    revs = scmutil.revrange(unfi, ["smartlog()"])
    hashes = '|'.join(unfi[rev].hex() for rev in revs)
    markers = hgcmd(debugcommands.debugobsolete, rev=[])
    pat = re.compile('(^.*(?:'+hashes+').*$)', re.MULTILINE)
    relevant = pat.findall(markers)
    return "\n".join(relevant)
Пример #26
0
 def getpatches(revs):
     prev = repo['.'].rev()
     for r in scmutil.revrange(repo, revs):
         if r == prev and (repo[None].files() or repo[None].deleted()):
             ui.warn(_('warning: working directory has '
                       'uncommitted changes\n'))
         output = cStringIO.StringIO()
         cmdutil.export(repo, [r], fp=output,
                      opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Пример #27
0
 def getpatches(revs):
     prev = repo['.'].rev()
     for r in scmutil.revrange(repo, revs):
         if r == prev and (repo[None].files() or repo[None].deleted()):
             ui.warn(
                 _('warning: working directory has '
                   'uncommitted changes\n'))
         output = cStringIO.StringIO()
         cmdutil.export(repo, [r], fp=output, opts=patch.diffopts(ui, opts))
         yield output.getvalue().split('\n')
Пример #28
0
def close_branch(ui, repo, *revs, **opts):
    """close the given head revisions

    This is equivalent to checking out each revision in a clean tree and running
    ``hg commit --close-branch``, except that it doesn't change the working
    directory.

    The commit message must be specified with -l or -m.
    """
    def docommit(rev):
        cctx = context.memctx(
            repo,
            parents=[rev, None],
            text=message,
            files=[],
            filectxfn=None,
            user=opts.get(b'user'),
            date=opts.get(b'date'),
            extra=extra,
        )
        tr = repo.transaction(b'commit')
        ret = repo.commitctx(cctx, True)
        bookmarks.update(repo, [rev, None], ret)
        cctx.markcommitted(ret)
        tr.close()

    opts = pycompat.byteskwargs(opts)

    revs += tuple(opts.get(b'rev', []))
    revs = scmutil.revrange(repo, revs)

    if not revs:
        raise error.Abort(_(b'no revisions specified'))

    heads = []
    for branch in repo.branchmap():
        heads.extend(repo.branchheads(branch))
    heads = {repo[h].rev() for h in heads}
    for rev in revs:
        if rev not in heads:
            raise error.Abort(_(b'revision is not an open head: %d') % rev)

    message = cmdutil.logmessage(ui, opts)
    if not message:
        raise error.Abort(_(b"no commit message specified with -l or -m"))
    extra = {b'close': b'1'}

    with repo.wlock(), repo.lock():
        for rev in revs:
            r = repo[rev]
            branch = r.branch()
            extra[b'branch'] = branch
            docommit(r)
    return 0
Пример #29
0
def hide(ui, repo, *revs, **opts):
    """hide changesets and their descendants

    Hidden changesets are still accessible by their hashes which can be found
    in ``hg journal``.

    If a parent of the working directory is hidden, then the working directory
    will automatically be updated to the most recent available ancestor of the
    hidden parent.

    If there is a bookmark pointing to the commit it will be removed.
    """
    revs = list(revs) + opts.pop('rev', [])
    revs = set(scmutil.revrange(repo, revs))
    hidectxs = list(repo.set("(%ld)::", revs))

    if not hidectxs:
        raise error.Abort(_('nothing to hide'))

    with repo.wlock(), repo.lock(), repo.transaction('hide') as tr:
        # revs to be hidden
        for ctx in hidectxs:
            if not ctx.mutable():
                raise error.Abort(
                    _('cannot hide immutable changeset: %s') % ctx,
                    hint="see 'hg help phases' for details")

        wdp = repo['.']
        newnode = wdp

        while newnode in hidectxs:
            newnode = newnode.parents()[0]

        if newnode.node() != wdp.node():
            cmdutil.bailifchanged(repo, merge=False)
            hg.update(repo, newnode, False)
            ui.status(_('working directory now at %s\n')
                      % ui.label(str(newnode), 'node'))

        # create markers
        obsolete.createmarkers(repo, [(r, []) for r in hidectxs],
                               operation='hide')
        ui.status(_('%i changesets hidden\n') % len(hidectxs))

        # remove bookmarks pointing to hidden changesets
        hnodes = [r.node() for r in hidectxs]
        bmchanges = []
        for book, node in bookmarksmod.listbinbookmarks(repo):
            if node in hnodes:
                bmchanges.append((book, None))
        repo._bookmarks.applychanges(repo, tr, bmchanges)

        if len(bmchanges) > 0:
            ui.status(_('%i bookmarks removed\n') % len(bmchanges))
Пример #30
0
def email(ui, repoagent, *revs, **opts):
    """send changesets by email"""
    from tortoisehg.hgqt import hgemail
    # TODO: same options as patchbomb
    if opts.get('rev'):
        if revs:
            raise util.Abort(_('use only one form to specify the revision'))
        revs = opts.get('rev')

    repo = repoagent.rawRepo()
    revs = scmutil.revrange(repo, revs)
    return hgemail.EmailDialog(repoagent, revs)
Пример #31
0
def email(ui, repoagent, *revs, **opts):
    """send changesets by email"""
    from tortoisehg.hgqt import hgemail
    # TODO: same options as patchbomb
    if opts.get('rev'):
        if revs:
            raise util.Abort(_('use only one form to specify the revision'))
        revs = opts.get('rev')

    repo = repoagent.rawRepo()
    revs = scmutil.revrange(repo, revs)
    return hgemail.EmailDialog(repoagent, revs)
Пример #32
0
 def __init__(self, ui, repotype, path, revs=None):
     common.converter_source.__init__(self, ui, repotype, path, revs)
     self.ignoreerrors = ui.configbool(b'convert', b'hg.ignoreerrors')
     self.ignored = set()
     self.saverev = ui.configbool(b'convert', b'hg.saverev')
     try:
         self.repo = hg.repository(self.ui, path)
         # try to provoke an exception if this isn't really a hg
         # repo, but some other bogus compatible-looking url
         if not self.repo.local():
             raise error.RepoError
     except error.RepoError:
         ui.traceback()
         raise NoRepo(_(b"%s is not a local Mercurial repository") % path)
     self.lastrev = None
     self.lastctx = None
     self._changescache = None, None
     self.convertfp = None
     # Restrict converted revisions to startrev descendants
     startnode = ui.config(b'convert', b'hg.startrev')
     hgrevs = ui.config(b'convert', b'hg.revs')
     if hgrevs is None:
         if startnode is not None:
             try:
                 startnode = self.repo.lookup(startnode)
             except error.RepoError:
                 raise error.Abort(
                     _(b'%s is not a valid start revision') % startnode)
             startrev = self.repo.changelog.rev(startnode)
             children = {startnode: 1}
             for r in self.repo.changelog.descendants([startrev]):
                 children[self.repo.changelog.node(r)] = 1
             self.keep = children.__contains__
         else:
             self.keep = util.always
         if revs:
             self._heads = [self.repo.lookup(r) for r in revs]
         else:
             self._heads = self.repo.heads()
     else:
         if revs or startnode is not None:
             raise error.Abort(
                 _(b'hg.revs cannot be combined with '
                   b'hg.startrev or --rev'))
         nodes = set()
         parents = set()
         for r in scmutil.revrange(self.repo, [hgrevs]):
             ctx = self.repo[r]
             nodes.add(ctx.node())
             parents.update(p.node() for p in ctx.parents())
         self.keep = nodes.__contains__
         self._heads = nodes - parents
Пример #33
0
def get_hgtags_from_heads(ui, repo, rev):
    from mercurial import scmutil
    heads = scmutil.revrange(repo,['heads(%d::)' % (rev)])
    ui.debug(_('get_hgtags_from_heads: rev: %d heads: %r\n') % (rev, heads))
    head_hgtags = dict()
    for h in heads:
        if '.hgtags' in repo[h]:
            hgtags = repo[h]['.hgtags'].data()
            hnode = hex(repo[h].node())
            ui.debug(_('get_hgtags_from_heads: head_hgtags[%s]:\n%s\n') 
                     % (hnode, hgtags))
            head_hgtags[hnode] = hgtags
    return head_hgtags
Пример #34
0
def tasks(ui, repo, *changesets, **opts):
    """show tasks related to the given revision.

    By default, the revision used is the parent of the working
    directory: use -r/--rev to specify a different revision.

    By default, the forge url used is https://www.cubicweb.org/. Use
    -U/--endpoint to specify a different cwclientlib endpoint. The
    endpoint id of the forge can be permanently defined into one of
    the mercurial configuration file::

    [jpl]
    endpoint = https://www.cubicweb.org/

    By default, done tasks are not displayed: use -a/--all to not filter
    tasks and display all.

    """
    changesets += tuple(opts.get('rev', []))
    if not changesets:
        changesets = ('.')
    revs = scmutil.revrange(repo, changesets)
    if not revs:
        raise util.Abort(
            _('no working directory or revision not found: '
              'please specify a known revision'))
    # we need to see hidden cs from here
    repo = repo.unfiltered()

    for rev in revs:
        precs = scmutil.revrange(repo, (rev, 'allprecursors(%s)' % rev))
        ctxhexs = list((node.short(repo.lookup(lrev)) for lrev in precs))
        showall = opts.get('all', None)
        with build_proxy(ui, opts) as client:
            try:
                print_tasks(client, ui, ctxhexs, showall=showall)
            except Exception as e:
                ui.write('no patch or no tasks for %s\n' %
                         node.short(repo.lookup(rev)))
Пример #35
0
 def __init__(self, ui, path, rev=None):
     converter_source.__init__(self, ui, path, rev)
     self.ignoreerrors = ui.configbool('convert', 'hg.ignoreerrors', False)
     self.ignored = set()
     self.saverev = ui.configbool('convert', 'hg.saverev', False)
     try:
         self.repo = hg.repository(self.ui, path)
         # try to provoke an exception if this isn't really a hg
         # repo, but some other bogus compatible-looking url
         if not self.repo.local():
             raise error.RepoError
     except error.RepoError:
         ui.traceback()
         raise NoRepo(_("%s is not a local Mercurial repository") % path)
     self.lastrev = None
     self.lastctx = None
     self._changescache = None, None
     self.convertfp = None
     # Restrict converted revisions to startrev descendants
     startnode = ui.config('convert', 'hg.startrev')
     hgrevs = ui.config('convert', 'hg.revs')
     if hgrevs is None:
         if startnode is not None:
             try:
                 startnode = self.repo.lookup(startnode)
             except error.RepoError:
                 raise util.Abort(_('%s is not a valid start revision')
                                  % startnode)
             startrev = self.repo.changelog.rev(startnode)
             children = {startnode: 1}
             for r in self.repo.changelog.descendants([startrev]):
                 children[self.repo.changelog.node(r)] = 1
             self.keep = children.__contains__
         else:
             self.keep = util.always
         if rev:
             self._heads = [self.repo[rev].node()]
         else:
             self._heads = self.repo.heads()
     else:
         if rev or startnode is not None:
             raise util.Abort(_('hg.revs cannot be combined with '
                                'hg.startrev or --rev'))
         nodes = set()
         parents = set()
         for r in scmutil.revrange(self.repo, [hgrevs]):
             ctx = self.repo[r]
             nodes.add(ctx.node())
             parents.update(p.node() for p in ctx.parents())
         self.keep = nodes.__contains__
         self._heads = nodes - parents
Пример #36
0
    def getoutgoing(dest, revs):
        '''Return the revisions present locally but not in dest'''
        url = ui.expandpath(dest or 'default-push', dest or 'default')
        url = hg.parseurl(url)[0]
        ui.status(_('comparing with %s\n') % util.hidepassword(url))

        revs = [r for r in scmutil.revrange(repo, revs) if r >= 0]
        if not revs:
            revs = [len(repo) - 1]
        revs = repo.revs('outgoing(%s) and ::%ld', dest or '', revs)
        if not revs:
            ui.status(_("no changes found\n"))
            return []
        return [str(r) for r in revs]
Пример #37
0
    def getoutgoing(dest, revs):
        '''Return the revisions present locally but not in dest'''
        url = ui.expandpath(dest or 'default-push', dest or 'default')
        url = hg.parseurl(url)[0]
        ui.status(_('comparing with %s\n') % util.hidepassword(url))

        revs = [r for r in scmutil.revrange(repo, revs) if r >= 0]
        if not revs:
            revs = [len(repo) - 1]
        revs = repo.revs('outgoing(%s) and ::%ld', dest or '', revs)
        if not revs:
            ui.status(_("no changes found\n"))
            return []
        return [str(r) for r in revs]
Пример #38
0
def get_hgtags_from_heads(ui, repo, rev):
    from mercurial import scmutil
    heads = scmutil.revrange(repo, ['heads(%d::)' % (rev)])
    ui.debug(_('get_hgtags_from_heads: rev: %d heads: %r\n') % (rev, heads))
    head_hgtags = dict()
    for h in heads:
        if '.hgtags' in repo[h]:
            hgtags = repo[h]['.hgtags'].data()
            hnode = hex(repo[h].node())
            ui.debug(
                _('get_hgtags_from_heads: head_hgtags[%s]:\n%s\n') %
                (hnode, hgtags))
            head_hgtags[hnode] = hgtags
    return head_hgtags
Пример #39
0
def verifysigs(ui, repo, *revrange, **opts):
    """verify manifest signatures

    Verify repository heads, the revision range specified or all
    changesets. The return code is one of:

    - 0 if all changesets had valid signatures
    - 1 if there were a changeset without a signature
    - 2 if an exception was raised while verifying a changeset
    - 3 if there were a changeset with a bad signature

    The final return code is the highest of the above.
    """
    if opts.get('only_heads'):
        revs = repo.heads()
    elif not revrange:
        revs = xrange(len(repo))
    else:
        revs = scmutil.revrange(repo, revrange)

    retcode = 0
    for rev in revs:
        ctx = repo[rev]
        h = ctxhash(ctx)
        extra = ctx.extra()
        sig = extra.get('signature')
        if not sig:
            msg = _("** no signature")
            retcode = max(retcode, 1)
        else:
            ui.debug(_("signature: %s\n") % sig)
            try:
                scheme, sig = sig.split(":", 1)
                verifyfunc = sigschemes[scheme][1]
                verified = verifyfunc(hex(h), sig, ctx.user(), quiet=True)
                if verified[0]:
                    if scheme == "gnupg":
                        msg = (_("good %s signature with key-id %s from %s") % 
                               (scheme, verified[1], verified[2]))
                    else:
                        msg = _("good %s signature") % scheme
                else:
                    msg = _("** bad %s signature on %s") % (scheme, short(h))
                    retcode = max(retcode, 3)
            except Exception, e:
                msg = _("** exception while verifying %s signature: %s") \
                    % (scheme, e)
                retcode = max(retcode, 2)
        ui.write("%d:%s: %s\n" % (ctx.rev(), ctx, msg))
Пример #40
0
def _getpatches(repo, revs, **opts):
    """return a list of patches for a list of revisions

    Each patch in the list is itself a list of lines.
    """
    ui = repo.ui
    prev = repo['.'].rev()
    for r in scmutil.revrange(repo, revs):
        if r == prev and (repo[None].files() or repo[None].deleted()):
            ui.warn(_('warning: working directory has '
                      'uncommitted changes\n'))
        output = cStringIO.StringIO()
        cmdutil.export(repo, [r], fp=output,
                     opts=patch.difffeatureopts(ui, opts, git=True))
        yield output.getvalue().split('\n')
Пример #41
0
def unhide(ui, repo, *revs, **opts):
    """unhide changesets and their ancestors
    """
    unfi = repo.unfiltered()
    revs = list(revs) + opts.pop('rev', [])
    revs = set(scmutil.revrange(unfi, revs))
    ctxs = unfi.set("::(%ld) & obsolete()", revs)

    with repo.wlock(), repo.lock(), repo.transaction('unhide'):
        try:
            inhibit = extensions.find('inhibit')
            inhibit.revive(ctxs, operation='unhide')
        except KeyError:
            raise error.Abort(_('cannot unhide - inhibit extension '
                                'is not enabled'))
Пример #42
0
 def parents_from_source(self):
     revrange = scmutil.revrange(self.source,  self.src_revs)
     self.graph = list(graphmod.dagwalker(self.source, revrange))
     gid2rev = dict(
         ((id, ctx.rev()) for id, C, ctx, parents in self.graph))
     # graphmod returns a graph of all possible connections through
     # the underlying original graph.
     # We want a minimal graph instead, that goes through our nodes if it
     # can.
     # get the full graph of all nodes first
     # we ignore missing parents, too, we collect those in self.roots
     for _id, C, src_ctx, parents in self.graph:
         local_parents = set((
             gid2rev.get(p[1]) for p in parents if p[0] != b'M'))
         yield src_ctx.rev(), local_parents
Пример #43
0
def getrevstofix(ui, repo, opts):
    """Returns the set of revision numbers that should be fixed"""
    revs = set(scmutil.revrange(repo, opts['rev']))
    for rev in revs:
        checkfixablectx(ui, repo, repo[rev])
    if revs:
        cmdutil.checkunfinished(repo)
        checknodescendants(repo, revs)
    if opts.get('working_dir'):
        revs.add(wdirrev)
        if list(merge.mergestate.read(repo).unresolved()):
            raise error.Abort('unresolved conflicts', hint="use 'hg resolve'")
    if not revs:
        raise error.Abort(
            'no changesets specified', hint='use --rev or --working-dir')
    return revs
Пример #44
0
def overridepull(orig, ui, repo, source=None, **opts):
    revsprepull = len(repo)
    if not source:
        source = 'default'
    repo.lfpullsource = source
    if opts.get('rebase', False):
        repo._isrebasing = True
        try:
            if opts.get('update'):
                del opts['update']
                ui.debug('--update and --rebase are not compatible, ignoring '
                         'the update flag\n')
            del opts['rebase']
            cmdutil.bailifchanged(repo)
            origpostincoming = commands.postincoming

            def _dummy(*args, **kwargs):
                pass

            commands.postincoming = _dummy
            try:
                result = commands.pull(ui, repo, source, **opts)
            finally:
                commands.postincoming = origpostincoming
            revspostpull = len(repo)
            if revspostpull > revsprepull:
                result = result or rebase.rebase(ui, repo)
        finally:
            repo._isrebasing = False
    else:
        result = orig(ui, repo, source, **opts)
    revspostpull = len(repo)
    lfrevs = opts.get('lfrev', [])
    if opts.get('all_largefiles'):
        lfrevs.append('pulled()')
    if lfrevs and revspostpull > revsprepull:
        numcached = 0
        repo.firstpulled = revsprepull  # for pulled() revset expression
        try:
            for rev in scmutil.revrange(repo, lfrevs):
                ui.note(_('pulling largefiles for revision %s\n') % rev)
                (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
                numcached += len(cached)
        finally:
            del repo.firstpulled
        ui.status(_("%d largefiles cached\n") % numcached)
    return result
Пример #45
0
def patch_changes(ui, repo, patchfile=None, **opts):
    '''Given a patch, look at what files it changes, and map a function over
    the changesets that touch overlapping files.

    Scan through the last LIMIT commits to find the relevant changesets

    The patch may be given as a file or a URL. If no patch is specified,
    the changes in the working directory will be used. If there are no
    changes, the topmost applied patch in your mq repository will be used.

    Alternatively, the -f option may be used to pass in one or more files
    that will be used directly.
    '''

    if opts['file']:
        changedFiles = fullpaths(ui, repo, opts['file'])
    elif opts['rev']:
        revs = scmutil.revrange(repo, opts['rev'])
        if not revs:
            raise util.Abort("no changes found")
        filesInRevs = set()
        for rev in revs:
            for f in repo[rev].files():
                filesInRevs.add(f)
        changedFiles = sorted(filesInRevs)
    else:
        if patchfile is None:
            # we should use the current diff, or if that is empty, the top
            # applied patch in the patch queue
            ui.pushbuffer()
            commands.diff(ui, repo, git=True)
            diff = ui.popbuffer()
            changedFiles = fileRe.findall(diff)
            if len(changedFiles) > 0:
                source = "current diff"
            elif repo.mq:
                source = "top patch in mq queue"
                ui.pushbuffer()
                try:
                    commands.diff(ui, repo, change="qtip", git=True)
                except error.RepoLookupError, e:
                    raise util.Abort("no current diff, no mq patch to use")
                diff = ui.popbuffer()
            else:
                raise util.Abort("no changes found")
        else:
Пример #46
0
def patch_changes(ui, repo, patchfile=None, **opts):
    '''Given a patch, look at what files it changes, and map a function over
    the changesets that touch overlapping files.

    Scan through the last LIMIT commits to find the relevant changesets

    The patch may be given as a file or a URL. If no patch is specified,
    the changes in the working directory will be used. If there are no
    changes, the topmost applied patch in your mq repository will be used.

    Alternatively, the -f option may be used to pass in one or more files
    that will be used directly.
    '''

    if opts['file']:
        changedFiles = fullpaths(ui, repo, opts['file'])
    elif opts['rev']:
        revs = scmutil.revrange(repo, opts['rev'])
        if not revs:
            raise util.Abort("no changes found")
        filesInRevs = set()
        for rev in revs:
            for f in repo[rev].files():
                filesInRevs.add(f)
        changedFiles = sorted(filesInRevs)
    else:
        if patchfile is None:
            # we should use the current diff, or if that is empty, the top
            # applied patch in the patch queue
            ui.pushbuffer()
            commands.diff(ui, repo, git=True)
            diff = ui.popbuffer()
            changedFiles = fileRe.findall(diff)
            if len(changedFiles) > 0:
                source = "current diff"
            elif repo.mq:
                source = "top patch in mq queue"
                ui.pushbuffer()
                try:
                    commands.diff(ui, repo, change="qtip", git=True)
                except error.RepoLookupError, e:
                    raise util.Abort("no current diff, no mq patch to use")
                diff = ui.popbuffer()
            else:
                raise util.Abort("no changes found")
        else:
Пример #47
0
def amendtocommit(ui, repo, commitspec):
    """amend to a specific commit
    """
    with repo.wlock(), repo.lock():
        originalcommits = list(repo.set("::. - public()"))
        try:
            revs = scmutil.revrange(repo, [commitspec])
        except error.RepoLookupError:
            raise error.Abort(_("revision '%s' cannot be found")
                              % commitspec)
        if len(revs) > 1:
            raise error.Abort(_("'%s' refers to multiple changesets")
                              % commitspec)
        targetcommit = repo[revs.first()]
        if targetcommit not in originalcommits:
            raise error.Abort(_("revision '%s' is not a parent of "
                              'the working copy' % commitspec))

        tempcommit = repo.commit(text="tempCommit")

        if not tempcommit:
            raise error.Abort(_('no pending changes to amend'))

        tempcommithex = hex(tempcommit)

        fp = tempfile.NamedTemporaryFile()
        try:
            found = False
            for curcommit in originalcommits:
                fp.write("pick " + str(curcommit) + "\n")
                if curcommit == targetcommit:
                    fp.write("roll " + tempcommithex[:12] + "\n")
                    found = True
            if not found:
                raise error.Abort(_("revision '%s' cannot be found")
                                  % commitspec)
            fp.flush()
            try:
                histedit.histedit(ui, repo, commands=fp.name)
            except error.InterventionRequired:
                ui.warn(_('amend --to encountered an issue - '
                        'use hg histedit to continue or abort'))
                raise
        finally:
            fp.close()
Пример #48
0
def overridepull(orig, ui, repo, source=None, **opts):
    revsprepull = len(repo)
    if not source:
        source = 'default'
    repo.lfpullsource = source
    if opts.get('rebase', False):
        repo._isrebasing = True
        try:
            if opts.get('update'):
                del opts['update']
                ui.debug('--update and --rebase are not compatible, ignoring '
                         'the update flag\n')
            del opts['rebase']
            cmdutil.bailifchanged(repo)
            origpostincoming = commands.postincoming
            def _dummy(*args, **kwargs):
                pass
            commands.postincoming = _dummy
            try:
                result = commands.pull(ui, repo, source, **opts)
            finally:
                commands.postincoming = origpostincoming
            revspostpull = len(repo)
            if revspostpull > revsprepull:
                result = result or rebase.rebase(ui, repo)
        finally:
            repo._isrebasing = False
    else:
        result = orig(ui, repo, source, **opts)
    revspostpull = len(repo)
    lfrevs = opts.get('lfrev', [])
    if opts.get('all_largefiles'):
        lfrevs.append('pulled()')
    if lfrevs and revspostpull > revsprepull:
        numcached = 0
        repo.firstpulled = revsprepull # for pulled() revset expression
        try:
            for rev in scmutil.revrange(repo, lfrevs):
                ui.note(_('pulling largefiles for revision %s\n') % rev)
                (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
                numcached += len(cached)
        finally:
            del repo.firstpulled
        ui.status(_("%d largefiles cached\n") % numcached)
    return result
Пример #49
0
def accept(ui, repo, *changesets, **opts):
    """accept patches corresponding to specified revisions

    By default, the revision used is the parent of the working
    directory: use -r/--rev to specify a different revision.

    """
    changesets += tuple(opts.get('rev', []))
    if not changesets:
        changesets = ('.')
    revs = scmutil.revrange(repo, changesets)
    if not revs:
        raise util.Abort(_('no working directory: please specify a revision'))
    ctxhexs = (node.short(repo.lookup(rev)) for rev in revs)

    with build_proxy(ui, opts) as client:
        acknowledge(client, ctxhexs)
    showreview(ui, repo, *changesets, **opts)
Пример #50
0
def make_ticket(ui, repo, *changesets, **opts):
    """create new tickets for the specified revisions
    """
    changesets += tuple(opts.get('rev', []))
    if not changesets:
        changesets = ('.', )
    revs = scmutil.revrange(repo, changesets)
    if not revs:
        raise util.Abort(_('no working directory: please specify a revision'))

    with build_proxy(ui, opts) as client:
        for rev in revs:
            ticket = sudo_make_me_a_ticket(client,
                                           repo,
                                           rev,
                                           version=opts.get('done_in', ''),
                                           kind=opts.get('type', 'bug'))
            ui.write("{0} {1}\n".format(
                rev, ticket[0][0] if ticket[0] else 'FAILED'))
Пример #51
0
def listtc(ui, repo, *changesets, **opts):
    """list available test configurations for the given revisions.

    By default, the revision used is the parent of the working
    directory: use -r/--rev to specify a different revision.

    """
    changesets += tuple(opts.get('rev', []))
    if not changesets:
        changesets = ('.')
    revs = scmutil.revrange(repo, changesets)
    if not revs:
        raise util.Abort(_('no working directory: please specify a revision'))
    ctxhexs = [node.short(repo.lookup(rev)) for rev in revs]

    with build_proxy(ui, opts) as client:
        results = list_tc(client, ctxhexs)
        ui.write('{}\n'.format('\n'.join('{0} ({1})'.format(str(tc), str(tn))
                                         for (tc, tn) in results)))
Пример #52
0
def prefetch(ui, repo, *pats, **opts):
    """prefetch file revisions from the server

    Prefetchs file revisions for the specified revs and stores them in the
    local remotefilelog cache.  If no rev is specified, it uses your current
    commit. File names or patterns can be used to limit which files are
    downloaded.

    Return 0 on success.
    """
    if not shallowrepo.requirement in repo.requirements:
        raise util.Abort(_("repo is not shallow"))

    if not opts.get('rev'):
        opts['rev'] = '.'

    m = scmutil.matchall(repo)
    revs = scmutil.revrange(repo, opts.get('rev'))

    repo.prefetch(revs, pats=pats, opts=opts)
Пример #53
0
def prefetch(ui, repo, *pats, **opts):
    """prefetch file revisions from the server

    Prefetchs file revisions for the specified revs and stores them in the
    local remotefilelog cache.  If no rev is specified, it uses your current
    commit. File names or patterns can be used to limit which files are
    downloaded.

    Return 0 on success.
    """
    if not shallowrepo.requirement in repo.requirements:
        raise util.Abort(_("repo is not shallow"))

    if not opts.get('rev'):
        opts['rev'] = '.'

    m = scmutil.matchall(repo)
    revs = scmutil.revrange(repo, opts.get('rev'))

    repo.prefetch(revs, pats=pats, opts=opts)
Пример #54
0
def prefetch(ui, repo, *pats, **opts):
    """prefetch file revisions from the server

    Prefetchs file revisions for the specified revs and stores them in the
    local remotefilelog cache.  If no rev is specified, the default rev is
    used which is the union of dot, draft, pullprefetch and bgprefetchrev.
    File names or patterns can be used to limit which files are downloaded.

    Return 0 on success.
    """
    if not shallowrepo.requirement in repo.requirements:
        raise error.Abort(_("repo is not shallow"))

    opts = resolveprefetchopts(ui, opts)
    revs = scmutil.revrange(repo, opts.get('rev'))
    repo.prefetch(revs, opts.get('base'), pats, opts)

    # Run repack in background
    if opts.get('repack'):
        repackmod.backgroundrepack(repo, incremental=True)
Пример #55
0
def graphlog(ui, repo, *pats, **opts):
    """show revision history alongside an ASCII revision graph

    Print a revision history alongside a revision graph drawn with
    ASCII characters.

    Nodes printed as an @ character are parents of the working
    directory.
    """

    check_unsupported_flags(pats, opts)

    revs = sorted(scmutil.revrange(repo, [revset(pats, opts)]), reverse=1)
    limit = cmdutil.loglimit(opts)
    if limit is not None:
        revs = revs[:limit]
    revdag = graphmod.dagwalker(repo, revs)

    displayer = show_changeset(ui, repo, opts, buffered=True)
    showparents = [ctx.node() for ctx in repo[None].parents()]
    generate(ui, revdag, displayer, showparents, asciiedges)