This series adds support for highlighting a set of changesets in the
log & graphlog command. It's done in the third patch.
The first patch fixes a bug triggered in the third patch, and the
second patch makes the parent changesets coloured just like the
current changeset. It's not necessary, strictly speaking, but nice
IMHO.
--
- Dan
_______________________________________________
Mercurial-devel mailing list
Mercuri...@selenic.com
http://selenic.com/mailman/listinfo/mercurial-devel
diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -290,7 +290,7 @@ class colorui(uimod.ui):
s = _styles.get(l, '')
if s:
effects.append(s)
- effects = ''.join(effects)
+ effects = ' '.join(effects)
if effects:
return '\n'.join([render_effects(s, effects)
for s in msg.split('\n')])
diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -193,6 +193,7 @@ _styles = {'grep.match': 'red bold',
'diffstat.inserted': 'green',
'ui.prompt': 'yellow',
'log.changeset': 'yellow',
+ 'log.parent': 'yellow',
'resolve.resolved': 'green bold',
'resolve.unresolved': 'red bold',
'status.added': 'green bold',
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -558,8 +558,8 @@ log -p -l2 --color=always
\x1b[0;32m+postm\x1b[0m (esc)
\x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
- parent: 3:e62f78d544b4
- parent: 4:ddb82e70d1a1
+ \x1b[0;33mparent: 3:e62f78d544b4\x1b[0m (esc)
+ \x1b[0;33mparent: 4:ddb82e70d1a1\x1b[0m (esc)
user: test
date: Thu Jan 01 00:00:01 1970 +0000
summary: m12
The option only works when using the default templater, not a custom
style. I chose to make the option itself part of the 'color'
extension, as the color machinery isn't prepared for converting a textual
highlight to using color exclusively.
diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -102,7 +102,8 @@ disable color.
import os, sys
-from mercurial import commands, dispatch, extensions, ui as uimod, util
+from mercurial import commands, cmdutil, dispatch, error, extensions
+from mercurial import ui as uimod, util
from mercurial.i18n import _
# start and stop parameters for effects
@@ -194,6 +195,7 @@ _styles = {'grep.match': 'red bold',
'ui.prompt': 'yellow',
'log.changeset': 'yellow',
'log.parent': 'yellow',
+ 'log.highlighted': 'inverse',
'resolve.resolved': 'green bold',
'resolve.unresolved': 'red bold',
'status.added': 'green bold',
@@ -352,6 +354,21 @@ def extsetup(ui):
_("when to colorize (boolean, always, auto, or never)"),
_('TYPE')))
+ highlightedoption = ('H', 'highlight', [],
+ _('highlight the specified revisions'), _('REV'))
+
+ def addopt(cmd, table, option):
+ cmdutil.findcmd(cmd, table)[1][1].append(option)
+
+ for cmd in 'incoming', 'log', 'outgoing':
+ addopt(cmd, commands.table, highlightedoption)
+
+ try:
+ glog = extensions.find('graphlog')
+ addopt('glog', glog.cmdtable, highlightedoption)
+ except KeyError:
+ pass
+
if os.name != 'nt':
w32effects = None
else:
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -752,7 +752,7 @@ def diffordiffstat(ui, repo, diffopts, n
class changeset_printer(object):
'''show changeset information when templating not requested.'''
- def __init__(self, ui, repo, patch, diffopts, buffered):
+ def __init__(self, ui, repo, patch, diffopts, buffered, highlights):
self.ui = ui
self.repo = repo
self.buffered = buffered
@@ -762,6 +762,7 @@ class changeset_printer(object):
self.hunk = {}
self.lastheader = None
self.footer = None
+ self.highlights = highlights
def flush(self, rev):
if rev in self.header:
@@ -806,8 +807,12 @@ class changeset_printer(object):
parents = [(p, hexfunc(log.node(p)))
for p in self._meaningful_parentrevs(log, rev)]
+ label = 'log.changeset'
+ if rev in self.highlights:
+ label += ' log.highlighted'
+
self.ui.write(_("changeset: %d:%s\n") % (rev, hexfunc(changenode)),
- label='log.changeset')
+ label=label)
branch = ctx.branch()
# don't show the default branch name
@@ -821,8 +826,11 @@ class changeset_printer(object):
self.ui.write(_("tag: %s\n") % tag,
label='log.tag')
for parent in parents:
+ label = 'log.parent'
+ if parent[0] in self.highlights:
+ label += ' log.highlighted'
self.ui.write(_("parent: %d:%s\n") % parent,
- label='log.parent')
+ label=label)
if self.ui.debugflag:
mnode = ctx.manifestnode()
@@ -910,7 +918,8 @@ class changeset_templater(changeset_prin
'''format changeset information.'''
def __init__(self, ui, repo, patch, diffopts, mapfile, buffered):
- changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered)
+ changeset_printer.__init__(self, ui, repo, patch, diffopts, buffered,
+ None)
formatnode = ui.debugflag and (lambda x: x) or (lambda x: x[:12])
defaulttempl = {
'parent': '{rev}:{node|formatnode} ',
@@ -1031,6 +1040,11 @@ def show_changeset(ui, repo, opts, buffe
else:
style = opts.get('style')
+ if opts.get('highlight'):
+ highlights = revrange(repo, opts['highlight'])
+ else:
+ highlights = []
+
# ui settings
if not (tmpl or style):
tmpl = ui.config('ui', 'logtemplate')
@@ -1040,7 +1054,7 @@ def show_changeset(ui, repo, opts, buffe
style = util.expandpath(ui.config('ui', 'style', ''))
if not (tmpl or style):
- return changeset_printer(ui, repo, patch, opts, buffered)
+ return changeset_printer(ui, repo, patch, opts, buffered, highlights)
mapfile = None
if style and not tmpl:
diff --git a/tests/test-glog.t b/tests/test-glog.t
--- a/tests/test-glog.t
+++ b/tests/test-glog.t
@@ -1428,3 +1428,21 @@ Test log -G options
$ hg log -G --follow a
abort: -G/--graph option is incompatible with --follow with file argument
[255]
+
+Graphlog with highlighting
+
+ $ hg --config extensions.color= --config color.mode=ansi \
+ > log -G -l2 --color=always --highlight=tip
+ @ \x1b[0;33;7mchangeset: 36:95fa8febd08a\x1b[0m (esc)
+ | tag: tip
+ | \x1b[0;33mparent: 35:9159c3644c5e\x1b[0m (esc)
+ | \x1b[0;33mparent: 35:9159c3644c5e\x1b[0m (esc)
+ | user: test
+ | date: Thu Jan 01 00:00:36 1970 +0000
+ | summary: (36) buggy merge: identical parents
+ |
+ o \x1b[0;33mchangeset: 35:9159c3644c5e\x1b[0m (esc)
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: 0
+ |
diff --git a/tests/test-log.t b/tests/test-log.t
--- a/tests/test-log.t
+++ b/tests/test-log.t
@@ -571,6 +571,24 @@ log -p -l2 --color=always
\x1b[0;32m+b2\x1b[0m (esc)
+Log with highlighting
+
+ $ hg --config extensions.color= --config color.mode=ansi \
+ > log -l2 --color=always --highlight=tip
+ \x1b[0;33;7mchangeset: 6:2404bbcab562\x1b[0m (esc)
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:01 1970 +0000
+ summary: b1.1
+
+ \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
+ \x1b[0;33mparent: 3:e62f78d544b4\x1b[0m (esc)
+ \x1b[0;33mparent: 4:ddb82e70d1a1\x1b[0m (esc)
+ user: test
+ date: Thu Jan 01 00:00:01 1970 +0000
+ summary: m12
+
+
log -r tip --stat
Queued, thanks.
--
Mathematics is the supreme nostalgia of our time.
People who think this feature is useful/good should explain why. I'm a
little skeptical.
--
Mathematics is the supreme nostalgia of our time.
It is nice for example with "outgoing()", I can easily see how the
outgoing csets fit into the whole graph.
Benoit
It's kind of problematic to me that on a stock install (ie color not
enabled), -H is a no-op. If we do something like this, it should a) have
a meaningful non-color effect and b) have an appropriate non-color name.
See <em> vs <i> in HTML for comparison.
--
Mathematics is the supreme nostalgia of our time.
If you don't have color enabled, you won't see -H.
cheers,
Benoit
Then I'd say it's too invasive of the core. Either it's general-purpose
or it shouldn't be making the log core even hairier.
--
Mathematics is the supreme nostalgia of our time.
I'm the one who suggested the feature. It was triggered by Benoit's
suggestion that we have a "sample(undecidedset)" revset to visualize
how set discovery takes samples. But there's other uses. Basically, it
boils down to being able to see things in context:
* Where was this file touched, on what lines development?
* Same for authors.
* Highlight all ancestors/descendants of this node.
* Highlight this named branch.
In fact, I think we should maybe revisit the decision to try and align
log and glog. log is very much about speed and thus always walks the
changelog in revnum order. For glog, however, I think we should value
versatility over raw speed. It's a DAG visualizer. Once we see it as
such, we can do things like:
* Walk from all heads in breadth-first manner to get an overview of
what the heads are (maybe not exactly breadth-first, but a couple of
nodes at a time).
* Use the linearizing toposort of shrink-revlog and combine it with
the elision of linear runs (an old patch of mine) to get a concise
overview of branching/merging in a tree.
glog is very much about DAGs. I already took a first step in the
direction of making DAGs first class with dagutil.py (introduced by
set discovery). Benoit is working on moving the shrink-revlog toposort
there. Maybe we could also move Patrick's "redagging" (rebuilding a
DAG from a disconnected revset) there. So the more general DAG algos
would be clearly separate from visualizing them.
Then we could base glog on the DAGs exposed by dagutil. And we could
also easily add support for other visualizers like dot (which should
be configurable so it immediately launches a renderer and viewer) and
hgweb.
This way, glog and other visualizers could make the power of revsets
even more awesome.
>> > It's kind of problematic to me that on a stock install (ie color not
>> > enabled), -H is a no-op. If we do something like this, it should a) have
>> > a meaningful non-color effect and b) have an appropriate non-color name.
>> > See <em> vs <i> in HTML for comparison.
>>
>> If you don't have color enabled, you won't see -H.
>
> Then I'd say it's too invasive of the core. Either it's general-purpose
> or it shouldn't be making the log core even hairier.
It could, for instance, use a different node character like * for
highlighted nodes (like we use @ today for the dirstate parents). Or
we could allow folks to specify a prefix to use for the next text,
with a default taken from graphlog.highlightprefix.
-parren
Teaching revlog's sort() about toposort might be useful.
> Then we could base glog on the DAGs exposed by dagutil. And we could
> also easily add support for other visualizers like dot (which should
> be configurable so it immediately launches a renderer and viewer) and
> hgweb.
>
> This way, glog and other visualizers could make the power of revsets
> even more awesome.
I'm all for making glog cool. But I disagree about aligning it with log.
People are going to continue to expect feature parity with log where it
makes sense. And the current implementation of log is horrendous to the
point where it's no longer maintainable. By being reimplemented in terms
of revsets, I think graphlog has already passed it up.
Check this out:
$ time hg log -b stable -q | wc
1238 1238 23481
real 0m2.564s
user 0m2.413s
sys 0m0.100s
$ time hg log -r 'branch(stable)' -q | wc
1238 1238 23481
real 0m2.145s
user 0m2.040s
sys 0m0.073s
Revsets are faster (and much more powerful) than log's engine, and
that's even before the optimizer has gotten the chance to do anything
clever. The current log code wants to die, though we'll need to teach
revsets a bit about the file fast path first.
> >> > It's kind of problematic to me that on a stock install (ie color not
> >> > enabled), -H is a no-op. If we do something like this, it should a) have
> >> > a meaningful non-color effect and b) have an appropriate non-color name.
> >> > See <em> vs <i> in HTML for comparison.
> >>
> >> If you don't have color enabled, you won't see -H.
> >
> > Then I'd say it's too invasive of the core. Either it's general-purpose
> > or it shouldn't be making the log core even hairier.
>
> It could, for instance, use a different node character like * for
> highlighted nodes (like we use @ today for the dirstate parents). Or
> we could allow folks to specify a prefix to use for the next text,
> with a default taken from graphlog.highlightprefix.
Ok, let's figure that out. Here's a plan of attack:
- come up with a display-neutral name for the feature (compare <em> and
<i> in HTML)
- come up with a sensible way to display emphasized changesets (or
whatever we call them) in plain text
- implement the color part of it
Note that whatever we do for plain text (ie prefix with a * or indent or
whatever), we'll probably need to preserve when we turn color on to
minimize surprise.
Just so we have a concrete proposal to discuss, here's my take on '*'
prefixing:
o changeset: 14183:333def42e785
|\ tag: qparent
| | parent: 14181:bf951d58b917
| | parent: 14182:ec5886db9dc6
| | user: Matt Mackall <m...@selenic.com>
| | date: Wed May 04 08:21:50 2011 -0500
| | summary: merge with crew
| |
| o * changeset: 14182:ec5886db9dc6
| | * parent: 14160:fa2b596db182
| | * user: Sune Foldager <cr...@cyanite.org>
| | * date: Wed May 04 13:37:41 2011 +0200
| | * summary: tests: fix deprecated use of hg debugdata/debugindex
| |
o | changeset: 14181:bf951d58b917
|\ \ parent: 14180:1123bbba278d
| | | parent: 14159:31ec4d7eb63f
| | | user: Matt Mackall <m...@selenic.com>
| | | date: Tue May 03 22:04:23 2011 -0500
| | | summary: merge with stable
There are other possibilities like adding a new column 0:
o changeset: 14183:333def42e785
|\ tag: qparent
| | parent: 14181:bf951d58b917
| | parent: 14182:ec5886db9dc6
| | user: Matt Mackall <m...@selenic.com>
| | date: Wed May 04 08:21:50 2011 -0500
| | summary: merge with crew
| |
* | o changeset: 14182:ec5886db9dc6
* | | parent: 14160:fa2b596db182
* | | user: Sune Foldager <cr...@cyanite.org>
* | | date: Wed May 04 13:37:41 2011 +0200
* | | summary: tests: fix deprecated use of hg debugdata/debugindex
| |
o | changeset: 14181:bf951d58b917
|\ \ parent: 14180:1123bbba278d
| | | parent: 14159:31ec4d7eb63f
| | | user: Matt Mackall <m...@selenic.com>
| | | date: Tue May 03 22:04:23 2011 -0500
| | | summary: merge with stable
--
Mathematics is the supreme nostalgia of our time.
I would just comment (to hammer home the obvious) that external programs make heavy use of log and the speed of log is directly proportional to the speed of some of the Mercurial GUI's like eg MacHg, etc.
Also visualization is a cool topic but at some point you just get diminishing returns with ASCII based terminal visualization. At some point you need to switch to real graphics, subtle color shades, highlighting, etc. Thus its quite important that Mercurial allows speedy and easy access to these things so that the data can be grabbed for higher level visualization tools.
Cheers,
Jas
Ah, wow! I have obviously not always been paying attention at the sprint.
I like the new column 0 idea very much. As for display-neutral names,
I'm not a native speaker. Highlighting seems OK to me. Or, as you say
in the <em> comparison, an emphasis on some nodes. Your column 0 also
would allow one to support multiple emphasized revsets with different
labels (which could then be called a glog annotation):
hg glog --em 'branch(A)' --label A --em 'branch(B)' --label B
Then the actual highlighting machinery might define multiple color
specs like em1, em2, etc. in hgrc for this.
-parren
True, true. Glog takes you quite far, but as I said, I really think we
should have an interim representation of the sets and dags, including
emphasis, that is available to external tools. Some sort of JSON
representation maybe. And it's important that it operate at an
abstract DAG level (not on the base revlog DAG) so it can accommodate
alternate topologies like Patrick's condensed DAG. It should also
support different node types (csets, elisions, whatever) as I have
already introduced in graphlog earlier. And maybe something like CSS
styling hints.
-parren
Yes that would be quite nice. Regrettably, I find the output of debugdag quite hard to follow (and maybe this is just intrinsic to what its doing) or maybe its just my fault, and clearly the need for such a thing like debugdag is undeniable. But if there was a way to represent the dag info in a tiny bit of a nicer way that would be great. Or as you say some sort of other representation...
Cheers,
Jas
This output is not meant to be read by humans, but by things like
debugbuilddag, or by other parsers hooked up with glog, for instance
(I used this to compactly represent large DAGs during development of
setdiscovery).
-parren
No, no, this is bad :) The yellow lines are great now, they tell my eyes
where each changeset starts (and so there the preceding changeset ends).
I don't think we should change that.
--
Martin Geisler
aragost Trifork
Professional Mercurial support
http://mercurial.aragost.com/kick-start/
Yep. I understand its purpose. I am just saying I still couldn't understand it even
then. Ie I couldn't understand it enough to write a parser to get the relevant
information out of it. I have looked at documentation in dagparser.py but after
trying to fathom out what was going on here I gave up. I guess if I really studied
it I would be able to understand it... Still its pretty opaque to me :)
Thanks,
Jas