Beispiel #1
0
def extdiff(ui, repo, *pats, **opts):
    """use external program to diff repository (or selected files)

    Show differences between revisions for the specified files, using
    an external program. The default program used is diff, with
    default options "-Npru".

    To select a different program, use the -p/--program option. The
    program will be passed the names of two directories to compare. To
    pass additional options to the program, use -o/--option. These
    will be passed before the names of the directories to compare.

    When two revision arguments are given, then changes are shown
    between those revisions. If only one revision is specified then
    that revision is compared to the working directory, and, when no
    revisions are specified, the working directory files are compared
    to its parent."""
    opts = pycompat.byteskwargs(opts)
    program = opts.get("program")
    option = opts.get("option")
    if not program:
        program = "diff"
        option = option or ["-Npru"]
    cmdline = " ".join(map(util.shellquote, [program] + option))
    return dodiff(ui, repo, cmdline, pats, opts)
Beispiel #2
0
def countrate(ui, repo, amap, *pats, **opts):
    """Calculate stats"""
    opts = pycompat.byteskwargs(opts)
    if opts.get("dateformat"):

        def getkey(ctx):
            t, tz = ctx.date()
            date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
            return date.strftime(opts["dateformat"])

    else:
        tmpl = opts.get("oldtemplate") or opts.get("template")
        tmpl = cmdutil.makelogtemplater(ui, repo, tmpl)

        def getkey(ctx):
            ui.pushbuffer()
            tmpl.show(ctx)
            return ui.popbuffer()

    rate = {}
    df = False
    if opts.get("date"):
        df = util.matchdate(opts["date"])

    prog = progress.bar(ui, _("analyzing"), _("revisions"), len(repo))
    m = scmutil.match(repo[None], pats, opts)

    def prep(ctx, fns):
        rev = ctx.rev()
        if df and not df(ctx.date()[0]):  # doesn't match date format
            return

        key = getkey(ctx).strip()
        key = amap.get(key, key)  # alias remap
        if opts.get("changesets"):
            rate[key] = (rate.get(key, (0, ))[0] + 1, 0)
        else:
            parents = ctx.parents()
            if len(parents) > 1:
                ui.note(_("revision %d is a merge, ignoring...\n") % (rev, ))
                return

            ctx1 = parents[0]
            lines = changedlines(ui, repo, ctx1, ctx, fns)
            rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]

        prog.value += 1

    with prog:
        for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
            continue

    return rate
Beispiel #3
0
def snapshotshow(ui, repo, *args, **opts):
    """show the snapshot contents, given its revision id
    """
    opts = pycompat.byteskwargs(opts)
    cctx = getsnapshotctx(ui, repo, args)
    rev = cctx.hex()
    opts["rev"] = [rev]
    opts["patch"] = True
    revs, expr, filematcher = cmdutil.getlogrevs(repo.unfiltered(), [], opts)
    revmatchfn = filematcher(rev) if filematcher else None
    ui.pager("snapshotshow")
    displayer = cmdutil.show_changeset(ui, repo.unfiltered(), opts, buffered=True)
    with extensions.wrappedfunction(patch, "diff", _diff), extensions.wrappedfunction(
        cmdutil.changeset_printer, "_show", _show
    ), extensions.wrappedfunction(cmdutil.changeset_templater, "_show", _show):
        displayer.show(cctx, matchfn=revmatchfn)
        displayer.flush(cctx)
    displayer.close()
Beispiel #4
0
def mvcheck(orig, ui, repo, *pats, **opts):
    """Hook to check for moves at commit time"""
    opts = pycompat.byteskwargs(opts)
    renames = None
    disabled = opts.pop("no_automv", False) or opts.pop(
        "no-move-detection", False)
    if not disabled:
        threshold = ui.configint("automv", "similarity")
        if not 0 <= threshold <= 100:
            raise error.Abort(_("automv.similarity must be between 0 and 100"))
        if threshold > 0:
            match = scmutil.match(repo[None], pats, opts)
            added, removed = _interestingfiles(repo, match)
            renames = _findrenames(repo, match, added, removed,
                                   threshold / 100.0)

    with repo.wlock():
        if renames is not None:
            scmutil._markchanges(repo, (), (), renames)
        return orig(ui, repo, *pats, **pycompat.strkwargs(opts))
Beispiel #5
0
    def printsnapshots(self, ui, repo, **opts):
        opts = pycompat.byteskwargs(opts)
        fm = ui.formatter("snapshots", opts)
        if len(self.snapshots) == 0:
            ui.status(_("no snapshots created\n"))
        unfi = repo.unfiltered()
        for snapshotnode in self.snapshots:
            ctx = unfi[snapshotnode]
            message = ctx.description().split("\n")[0]
            metadataid = ctx.extra()["snapshotmetadataid"]
            if metadataid:
                metadataid = metadataid[:12]
            else:
                metadataid = "None"

            fm.startitem()
            # TODO(alexeyqu): print list of related files if --verbose
            fm.write("revision", "%s", str(ctx))
            fm.condwrite(ui.verbose, "snapshotmetadataid", "% 15s", metadataid)
            fm.write("message", " %s", message)
            fm.plain("\n")
        fm.end()
Beispiel #6
0
 def __call__(self, ui, repo, *pats, **opts):
     opts = pycompat.byteskwargs(opts)
     options = " ".join(map(util.shellquote, opts["option"]))
     if options:
         options = " " + options
     return dodiff(ui, repo, self._cmdline + options, pats, opts)
Beispiel #7
0
def _dosign(ui, repo, *revs, **opts):
    mygpg = newgpg(ui, **opts)
    opts = pycompat.byteskwargs(opts)
    sigver = "0"
    sigmessage = ""

    date = opts.get("date")
    if date:
        opts["date"] = util.parsedate(date)

    if revs:
        nodes = [repo.lookup(n) for n in revs]
    else:
        nodes = [
            node for node in repo.dirstate.parents() if node != hgnode.nullid
        ]
        if len(nodes) > 1:
            raise error.Abort(
                _("uncommitted merge - please provide a "
                  "specific revision"))
        if not nodes:
            nodes = [repo.changelog.tip()]

    for n in nodes:
        hexnode = hgnode.hex(n)
        ui.write(
            _("signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n)))
        # build data
        data = node2txt(repo, n, sigver)
        sig = mygpg.sign(data)
        if not sig:
            raise error.Abort(_("error while signing"))
        sig = binascii.b2a_base64(sig)
        sig = sig.replace("\n", "")
        sigmessage += "%s %s %s\n" % (hexnode, sigver, sig)

    # write it
    if opts["local"]:
        repo.localvfs.append("localsigs", sigmessage)
        return

    if not opts["force"]:
        msigs = match.exact(repo.root, "", [".hgsigs"])
        if any(repo.status(match=msigs, unknown=True, ignored=True)):
            raise error.Abort(
                _("working copy of .hgsigs is changed "),
                hint=_("please commit .hgsigs manually"),
            )

    sigsfile = repo.wvfs(".hgsigs", "ab")
    sigsfile.write(sigmessage)
    sigsfile.close()

    if ".hgsigs" not in repo.dirstate:
        with repo.lock(), repo.transaction("add-signatures"):
            repo[None].add([".hgsigs"])

    if opts["no_commit"]:
        return

    message = opts["message"]
    if not message:
        # we don't translate commit messages
        message = "\n".join([
            "Added signature for changeset %s" % hgnode.short(n) for n in nodes
        ])
    try:
        editor = cmdutil.getcommiteditor(editform="gpg.sign",
                                         **pycompat.strkwargs(opts))
        repo.commit(message,
                    opts["user"],
                    opts["date"],
                    match=msigs,
                    editor=editor)
    except ValueError as inst:
        raise error.Abort(str(inst))
Beispiel #8
0
def journal(ui, repo, *args, **opts):
    """show history of the checked out commit or a bookmark

    Show the history of all the commits that were once the current commit. In
    other words, shows a list of your previously checked out commits.
    :hg:`journal` can be used to find older versions of commits (for example,
    when you want to revert to a previous state). It can also be used to
    discover commits that were previously hidden.

    By default, :hg:`journal` displays the history of the current commit. To
    display a list of commits pointed to by a bookmark, specify a bookmark
    name.

    Specify --all to show the history of both the current commit and all
    bookmarks. In the output for --all, bookmarks are listed by name, and '.'
    indicates the current commit.

    Specify -Tjson to produce machine-readable output.

    .. container:: verbose

       By default, :hg:`journal` only shows the commit hash and the
       corresponding command. Specify --verbose to also include the previous
       commit hash, user, and timestamp.

       Use -c/--commits to output log information about each commit hash. To
       customize the log output, you can also specify switches like '--patch',
       '--git', '--stat', and '--template'.

       If a bookmark name starts with 're:', the remainder of the name is
       treated as a regular expression. To match a name that actually starts
       with 're:', use the prefix 'literal:'.

    """
    opts = pycompat.byteskwargs(opts)
    name = "."
    if opts.get("all"):
        if args:
            raise error.Abort(
                _("You can't combine --all and filtering on a name"))
        name = None
    if args:
        name = args[0]

    fm = ui.formatter("journal", opts)
    ui.pager("journal")

    if not opts.get("template"):
        if name is None:
            displayname = _("the working copy and bookmarks")
        else:
            displayname = "'%s'" % name
        ui.status(_("previous locations of %s:\n") % displayname)

    limit = cmdutil.loglimit(opts)
    entry = None
    for count, entry in enumerate(repo.journal.filtered(name=name)):
        if count == limit:
            break
        newhashesstr = fm.formatlist(list(map(fm.hexfunc, entry.newhashes)),
                                     name="node",
                                     sep=",")
        oldhashesstr = fm.formatlist(list(map(fm.hexfunc, entry.oldhashes)),
                                     name="node",
                                     sep=",")

        fm.startitem()
        fm.condwrite(ui.verbose, "oldhashes", "%s -> ", oldhashesstr)
        fm.write("newhashes", "%s", newhashesstr)
        fm.condwrite(ui.verbose, "user", " %-8s", entry.user)
        fm.condwrite(
            opts.get("all") or name.startswith("re:"), "name", "  %-8s",
            entry.name)

        timestring = fm.formatdate(entry.timestamp, "%Y-%m-%d %H:%M %1%2")
        fm.condwrite(ui.verbose, "date", " %s", timestring)
        fm.write("command", "  %s\n", entry.command)

        if opts.get("commits"):
            displayer = cmdutil.show_changeset(ui, repo, opts, buffered=False)
            for hash in entry.newhashes:
                try:
                    ctx = repo[hash]
                    displayer.show(ctx)
                except error.RepoLookupError as e:
                    fm.write("repolookuperror", "%s\n\n", str(e))
            displayer.close()

    fm.end()

    if entry is None and not opts.get("template"):
        ui.status(_("no recorded locations\n"))