gout command for graphlog extension

Peter Arrenbrecht peter.arrenbrecht at gmail.com
Wed Nov 19 13:44:51 CST 2008


On Wed, Nov 19, 2008 at 6:57 PM, Alpár Jüttner <alpar at cs.elte.hu> wrote:
> Hi,
>
> Please find small extension to graphlog.py in the attachment. It
> provides a gout/goutgoing command, which is just the graphical
> counterpart of the standard out/outgoing. They eat exactly the same
> options.
>
> I think it is useful enough to get into the hg-crew. I used a "trial and
> error" approach when I wrote it, so I would really appreciate any
> reviews and comments.

Interesting. Still makes me think all of log, export, email should use
the same base cset walker so all would know how to do --outgoing etc.

Please post an inlined patch next time, it is easier to comment on. Meanwhile:

> # HG changeset patch
> # User Alpar Juttner <alpar at cs.elte.hu>
> # Date 1227111367 0
> # Node ID fa8dfccecd18eeb335639b0d0de1343bd738d856
> # Parent  564326a6ef9c0ff5a20c5f9ca96b6a52d921f67f
> Add 'goutgoing' command to graphlog extension
>
> diff --git a/hgext/graphlog.py b/hgext/graphlog.py
> --- a/hgext/graphlog.py
> +++ b/hgext/graphlog.py
> @@ -9,10 +9,11 @@
>  import os
>  import sys
>  from mercurial.cmdutil import revrange, show_changeset
> -from mercurial.commands import templateopts
> +from mercurial.commands import templateopts, logopts, remoteopts
>  from mercurial.i18n import _
>  from mercurial.node import nullrev
>  from mercurial.util import Abort, canonpath
> +from mercurial import hg, ui, cmdutil, url
>
>  def revisions(repo, start, stop):
>      """cset DAG generator yielding (rev, node, [parents]) tuples
> @@ -293,6 +294,63 @@
>
>      ascii(ui, grapher(graphabledag()))
>
> +def outgoing_revs(ui, repo, dest, opts):
> +    """cset DAG generator yielding (node, [parents]) tuples
> +
> +    This generator function walks through the revisions not found
> +    in the destination
> +    """
> +    limit = cmdutil.loglimit(opts)
> +    dest, revs, checkout = hg.parseurl(
> +        ui.expandpath(dest or 'default-push', dest or 'default'),
> +        opts.get('rev'))
> +    cmdutil.setremoteconfig(ui, opts)
> +    if revs:
> +        revs = [repo.lookup(rev) for rev in revs]
> +    other = hg.repository(ui, dest)
> +    ui.status(_('comparing with %s\n') % url.hidepassword(dest))
> +    o = repo.findoutgoing(other, force=opts.get('force'))
> +    if not o:
> +        ui.status(_("no changes found\n"))
> +        return
> +    o = repo.changelog.nodesbetween(o, revs)[0]
> +    o.reverse()
> +    revdict = {}
> +    for n in o:
> +        revdict[repo.changectx(n).rev()]=True

This might be a tad cheaper as something like

cl = repo.changelog
for n in o:
    revdict[cl.rev(n)]=True

or even

revdict = dict.fromkeys([cl.rev(n) for n in o])

though admittedly it would again introduce the plain revlog-based API
here, which is less stable than the ctx based one.

> +    count = 0
> +    for n in o:
> +        if count >= limit:
> +            break
> +        ctx = repo.changectx(n)
> +        parents = [p.rev() for p in ctx.parents() if p.rev() in revdict]
> +        parents.sort()
> +        yield (ctx, parents)
> +        count += 1
> +
> +def goutgoing(ui, repo, dest=None, **opts):
> +    """show the outgoing changesets alongside an ASCII revision graph
> +
> +    Print the outgoing changesets alongside a revision graph drawn with
> +    ASCII characters.
> +
> +    Nodes printed as an @ character are parents of the working
> +    directory.
> +    """
> +    revdag = outgoing_revs(ui, repo, dest, opts)
> +    repo_parents = repo.dirstate.parents()
> +    displayer = show_changeset(ui, repo, opts, buffered=True)
> +    def graphabledag():
> +        for (ctx, parents) in revdag:
> +            # log_strings is the list of all log strings to draw alongside
> +            # the graph.
> +            displayer.show(ctx)
> +            lines = displayer.hunk.pop(ctx.rev()).split("\n")[:-1]
> +            char = ctx.node() in repo_parents and '@' or 'o'
> +            yield (ctx.rev(), parents, char, lines)
> +
> +    ascii(ui, grapher(graphabledag()))

Can't we extract the graphabledag() method and use it for both glog and gout?

> +
>  cmdtable = {
>      "glog":
>          (graphlog,
> @@ -301,4 +359,13 @@
>            ('r', 'rev', [], _('show the specified revision or range')),
>           ] + templateopts,
>           _('hg glog [OPTION]... [FILE]')),
> +    "goutgoing|gout":

No need to specify gout as an alias when goutgoing already starts with
gout, I think.

> +        (goutgoing,
> +         [('f', 'force', None,
> +           _('run even when remote repository is unrelated')),
> +          ('r', 'rev', [],
> +           _('a specific revision up to which you would like to push')),
> +          ('n', 'newest-first', None, _('show newest record first')),

Is this option ever used?

> +         ] + logopts + remoteopts,
> +         _('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
>  }

-parren



More information about the Mercurial-devel mailing list