[PATCH 1 of 3 RFC v2] web: provide diffstat summary to the changeset page
Steven Brown
stevengbrown at gmail.com
Sun May 22 12:06:11 CDT 2011
On 23 May 2011 00:31, Matt Mackall <mpm at selenic.com> wrote:
> On Mon, 2011-05-23 at 00:25 +0800, Steven Brown wrote:
> > On 22 May 2011 04:25, Matt Mackall <mpm at selenic.com> wrote:
> > > On Thu, 2011-05-19 at 16:42 -0500, Matt Mackall wrote:
> > >> On Thu, 2011-05-19 at 21:19 +0800, Steven Brown wrote:
> > >> > # HG changeset patch
> > >> > # User Steven Brown <StevenGBrown at gmail.com>
> > >> > # Date 1305809487 -28800
> > >> > # Node ID de31c212265a9a89b67451e72dec11f2fb280968
> > >> > # Parent a75e0f4ba0ab91277b654416d93abd12aa50b940
> > >> > web: provide diffstat summary to the changeset page
> > >> >
> > >> > Add the diffstat keyword to the filenodelink template.
> > >> >
> > >> > diff --git a/mercurial/hgweb/webcommands.py
> > b/mercurial/hgweb/webcommands.py
> > >> > --- a/mercurial/hgweb/webcommands.py
> > >> > +++ b/mercurial/hgweb/webcommands.py
> > >> > @@ -257,11 +257,13 @@
> > >> >
> > >> > files = []
> > >> > parity = paritygen(web.stripecount)
> > >> > + diffstats = webutil.diffstatfunc(web.repo, ctx)
> > >> > for f in ctx.files():
> > >> > template = f in ctx and 'filenodelink' or 'filenolink'
> > >> > files.append(tmpl(template,
> > >> > node=ctx.hex(), file=f,
> > >> > - parity=parity.next()))
> > >> > + parity=parity.next(),
> > >> > + diffstat=lambda **x:
> diffstats(x['file'])))
> > >> >
> > >> > parity = paritygen(web.stripecount)
> > >> > style = web.config('web', 'style', 'paper')
> > >> > diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py
> > >> > --- a/mercurial/hgweb/webutil.py
> > >> > +++ b/mercurial/hgweb/webutil.py
> > >> > @@ -7,7 +7,7 @@
> > >> > # GNU General Public License version 2 or any later version.
> > >> >
> > >> > import os, copy
> > >> > -from mercurial import match, patch, scmutil, error, ui
> > >> > +from mercurial import match, patch, scmutil, error, ui, util
> > >> > from mercurial.node import hex, nullid
> > >> >
> > >> > def up(p):
> > >> > @@ -211,6 +211,18 @@
> > >> > yield tmpl('diffblock', parity=parity.next(),
> > >> > lines=prettyprintlines(''.join(block)))
> > >> >
> > >> > +def diffstatfunc(repo, ctx):
> > >> > + ''''Return a function that provides the diffstat histogram for
> a
> > file.'''
> > >> > +
> > >> > + hist = {}
> > >> > + def func(filename):
> > >> > + if not hist:
> > >> > + lines = util.iterlines(ctx.diff())
> > >> > + diffopts = patch.diffopts(repo.ui, untrusted=True)
> > >> > + hist.update(patch.diffstatdict(lines,
> git=diffopts.git))
> > >> > + return hist.get(filename)
> > >> > + return func
> > >> > +
> > >> > class sessionvars(object):
> > >> > def __init__(self, vars, start='?'):
> > >> > self.start = start
> > >> > diff --git a/mercurial/patch.py b/mercurial/patch.py
> > >> > --- a/mercurial/patch.py
> > >> > +++ b/mercurial/patch.py
> > >> > @@ -1736,8 +1736,11 @@
> > >> > yield (filename, adds, removes, isbinary)
> > >> >
> > >> > def diffstat(lines, width=80, git=False):
> > >> > + stats = list(diffstatdata(lines))
> > >> > + return _diffstat(stats, width, git)
> > >> > +
> > >> > +def _diffstat(stats, width=80, git=False):
> > >> > output = []
> > >> > - stats = list(diffstatdata(lines))
> > >> >
> > >> > maxtotal, maxname = 0, 0
> > >> > totaladds, totalremoves = 0, 0
> > >> > @@ -1805,3 +1808,13 @@
> > >> > else:
> > >> > yield (line, '')
> > >> > yield ('\n', '')
> > >> > +
> > >> > +def diffstatdict(lines, **kw):
> > >> > + '''Return a dictionary of file names to diffstat histograms.'''
> > >> > +
> > >> > + stats = list(diffstatdata(lines))
> > >> > + hist = {}
> > >> > + for stat, line in zip(stats, _diffstat(stats,
> **kw).splitlines()):
> > >> > + filename = stat[0]
> > >> > + hist[filename] = line[1 + len(filename):].lstrip()[1:]
> > >> > + return hist
> > >>
> > >> This patch looks mostly good, but this part in patch.py looks fishy.
> > >> It seems we're generating a diffstat data set, then rendering it into
> > >> text to get all the line lengths right, then parsing the text again.
> > >>
> > >> Seems like it'd be better to have an intermediate diffstathist
> function
> > >> that generated a dict of filename->(add, remove) tuples where
> plus/minus
> > >> are scaled such that the max add+remove = 1.0.
> > >
> > > I ended up hacking on this a bit, and now there's a diffstatsum
> function
> > > that does the bit that's needed here. Now you can divide the adds and
> > > removes in the stat data by the total of adds+removes from the sum to
> > > scale it.
> >
> > Great. It even simplifies the existing code.
> >
> > >> Then hgweb or diffstat() could decide how to render this. Then hgweb,
> > >> for instance, could use spans and colors to render a graphical,
> scalable
> > >> bar chart rather than using monospaced text.
> > >
> > > So now what's needed is a way to provide the data to hgweb in a way
> that
> > > it can be rendered nicely.
> > >
> > > Thoughts?
> > >
> > > --
> > > Mathematics is the supreme nostalgia of our time.
> > >
> >
> > This is what I now have in mind for the UI.
> >
> > coal, paper and spartan: Add an expand link to the list of files. A plus
> > symbol will do. When clicked, it expands to display the 'file',
> 'annotate',
> > 'diff' and 'revisions' links for each file (like monoblue) and also the
> > diffstat summary. If necessary, this expanded view could be loaded as a
> > separate page to avoid slowing down the initial page load.
> >
> > monoblue: Add the diffstat summary to the existing HTML table of files.
> >
> > gitweb: No changes. It is intended to look like git's gitweb.
> >
> > The diffstat summary will show the total number of changes for each file
> > followed by a horizontal bar chart:
> >
> > --------------------
> > 33 | | |
> > --------------------
> >
> > ^ ^
> > Adds (Green) Removes (Red)
> >
> > How does this sound?
>
> Excellent.
>
> So it seems the templater will need to get at least
>
> (file, total, addpct, removepct)
>
>
> --
> Mathematics is the supreme nostalgia of our time.
>
>
>
Perhaps we should give it (file, adds, removes, scale) instead, which would
allow the number of adds and removes to be displayed without rounding
errors. For example, a style may choose to display this information in a
tool-tip.
It also needs parity (for the row stripes) and node (for the links).
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20110523/7de88948/attachment.htm>
More information about the Mercurial-devel
mailing list