hg view vs. hg glog
Peter Arrenbrecht
peter.arrenbrecht at gmail.com
Sat Nov 8 04:57:19 CST 2008
On Fri, Nov 7, 2008 at 5:20 PM, Alpár Jüttner <alpar at cs.elte.hu> wrote:
> On Fri, 2008-11-07 at 17:05 +0100, Peter Arrenbrecht wrote:
>> On Fri, Nov 7, 2008 at 4:05 PM, Alpár Jüttner <alpar at cs.elte.hu> wrote:
>> > Hi,
>> >
>> > I've read on this list that 'hg glog' uses a more sophisticated
>> > algorithm for visualizing the revision graph than 'hg view' does.
>> > Indeed, 'hg glog' can sometimes create a much narrower graph.
>> >
>> > However 'hg view' is much better in a very important aspect: it tends to
>> > put the heads on the top of the graph, while with 'hg glog' the tip is
>> > on the top (of course), but the additional heads tends to disappear
>> > somewhere below.
>> >
>> > Wouldn't it be possible to raise the heads to the top in 'hg glog', too?
>>
>
>> hg glog currently walks the revs in commit order. It thus mimicks hg
>> log. Hence, I guess, its name. So I don't think this will change.
>
> If true, it a said news. I still hope the opposit.
>
>> But
>> I plan on looking into hg glog --merge to show only merge and head
>> nodes.
>
> Is that really useful? The merge commits typically give very few
> information. For example here is the last 20 merge commits of the
> hg-crew. I cannot distill too much from them.
>
> [snip]
I was thinking of something like this (output from a hacked version of
hg; patch is inlined below):
$ hg glog -l20 -c1
o 7331 Keep sessionvars with repository links added in a0843c82d1a2
[] thomas 22 hours
|
. ... (12 skipped)
|
o 7318 merge bookmarks [] benoit 2 days
|\
| o 7317 bookmarks: Test if rebase works with bookmarks [] piranha 2 days
| |
| o 7316 bookmarks: Use dirstate to determine the current node in
addchangegroup [] dsp 3 days
| |
o | 7315 tests: run svn tests only with svn bindings >1.3 [] dirkjan 2 days
| |
. | ... (2 skipped)
|/
o 7312 Shorten sleep in inotify test [] mpm 4 days
|
As opposed to:
$ hg glog -l20
o 7331 Keep sessionvars with repository links added in a0843c82d1a2
[] thomas 22 hours
|
o 7330 Fix test output for updated gitdiffs help and web template
cleanups [] thomas 22 hours
|
o 7329 Do not abort with inotify extension enabled, but not supported
by the system. [] thomas 22 hours
|
o 7328 Enhance gitdiffs help text [] thomas 22 hours
|
o 7327 Kill trailing whitespace in templates [] thomas 22 hours
|
o 7326 graphlog: move functions around, eliminate helper function []
dirkjan 24 hours
|
o 7325 graphlog: split the actual DAG grapher out into a separate
method [] peter 25 hours
|
o 7324 graphlog: rename some vars prior to refactoring [] peter 25 hours
|
o 7323 graphlog: make some comment lines more like others in
punctuation [] peter 25 hours
|
o 7322 patchbomb: fix indentation [] peter 25 hours
|
o 7321 patchbomb: move exportee class to top level [] peter 25 hours
|
o 7320 ui: log non-interactive default response to stdout when
verbose [] peter 25 hours
|
o 7319 export: fixed silent output file overwriting [] Ronny 2 days
|
o 7318 merge bookmarks [] benoit 2 days
|\
| o 7317 bookmarks: Test if rebase works with bookmarks [] piranha 2 days
| |
| o 7316 bookmarks: Use dirstate to determine the current node in
addchangegroup [] dsp 3 days
| |
o | 7315 tests: run svn tests only with svn bindings >1.3 [] dirkjan 2 days
| |
o | 7314 coal/paper: link repo name to hgweb root [] dirkjan 3 days
| |
o | 7313 paper: don't keep the menu affixed to the top [] dirkjan 3 days
|/
o 7312 Shorten sleep in inotify test [] mpm 4 days
|
Patch for this (applies on top of my latest submitted patch series for
graphlog.py):
diff --git a/hgext/graphlog.py b/hgext/graphlog.py
--- a/hgext/graphlog.py
+++ b/hgext/graphlog.py
@@ -30,6 +30,73 @@
yield (curr_rev, node, parents)
curr_rev -= 1
+def cset_nodes_summary(repo, startrev, stoprev, limitruns):
+ """cset DAG generator yielding (rev, node, [parents]) tuples
+
+ Like cset_nodes(), but limits linear runs to at most limitruns nodes.
+ Yields number of elided nodes as node when skipping linear runs.
+ """
+ assert startrev >= stoprev
+
+ expecting = {}
+ def expect(rev, parents):
+ for p in parents:
+ if not expecting.get(p):
+ expecting[p] = rev
+
+ skipfirstrev = None
+ skiplastparents = []
+ skiplen = 0
+ runlen = 0
+ prevrev = None
+ prevloneparentrev = None
+ currrev = startrev
+ while currrev >= stoprev:
+ skip = False
+ expectedby = expecting.get(currrev)
+ if expectedby:
+ del expecting[currrev]
+ parents = [x for x in repo.changelog.parentrevs(currrev) if x
!= nullrev]
+ if len(parents) > 1:
+ parents.sort()
+ prevloneparentrev = None
+ else:
+ skip = (currrev == prevloneparentrev
+ and (not expectedby or expectedby == prevrev))
+ if len(parents) > 0:
+ prevloneparentrev = parents[0]
+ else:
+ prevloneparentrev = None
+ if skip:
+ if skipfirstrev:
+ skiplastparents = parents
+ skiplen += 1
+ #print "-- ", currrev, " -> ", parents
+ else:
+ runlen += 1
+ if runlen >= limitruns:
+ #print "-< ", currrev, " -> ", parents
+ skipfirstrev = currrev
+ skiplastparents = parents
+ skiplen = 1
+ else:
+ runlen = 0
+ if skipfirstrev:
+ if skiplen < 2:
+ node = repo.changelog.node(skipfirstrev)
+ else:
+ node = skiplen # signal skip
+ #print "-> ", eliding, " -> ", elisionparents
+ yield (skipfirstrev, node, skiplastparents)
+ expect(skipfirstrev, skiplastparents)
+ skipfirstrev = None
+ if not skipfirstrev:
+ node = repo.changelog.node(currrev)
+ yield (currrev, node, parents)
+ expect(currrev, parents)
+ prevrev = currrev
+ currrev -= 1
+
def file_nodes(repo, path, start_rev, stop_rev):
"""file cset DAG generator yielding (rev, node, [parents]) tuples
@@ -298,6 +365,7 @@
"""
limit = get_limit(opts["limit"])
+ collapse = get_limit(opts["collapse_linear"])
(start_rev, stop_rev) = get_revs(repo, opts["rev"])
stop_rev = max(stop_rev, start_rev - limit + 1)
if start_rev == nullrev:
@@ -306,6 +374,8 @@
path = canonpath(repo.root, os.getcwd(), path)
if path:
revdag = file_nodes(repo, path, start_rev, stop_rev)
+ elif collapse < sys.maxint:
+ revdag = cset_nodes_summary(repo, start_rev, stop_rev, collapse)
else:
revdag = cset_nodes(repo, start_rev, stop_rev)
@@ -313,15 +383,19 @@
cs_printer = show_changeset(ui, repo, opts)
def graphabledag():
for (rev, node, parents) in revdag:
- # log_strings is the list of all log strings to draw alongside
- # the graph.
- ui.pushbuffer()
- cs_printer.show(rev, node)
- log_strings = ui.popbuffer().split("\n")[:-1]
- if node in repo_parents:
- node_ch = "@"
+ if isinstance(node, int):
+ node_ch = '.'
+ log_strings = [_('... (%i skipped)') % node]
else:
- node_ch = "o"
+ # log_strings is the list of all log strings to draw alongside
+ # the graph.
+ ui.pushbuffer()
+ cs_printer.show(rev, node)
+ log_strings = ui.popbuffer().split("\n")[:-1]
+ if node in repo_parents:
+ node_ch = "@"
+ else:
+ node_ch = "o"
yield (rev, parents, node_ch, log_strings)
ascii(ui, nodegrapher(graphabledag()))
@@ -332,6 +406,7 @@
[('l', 'limit', '', _('limit number of changes displayed')),
('p', 'patch', False, _('show patch')),
('r', 'rev', [], _('show the specified revision or range')),
+ ('c', 'collapse-linear', '', _('limit number of nodes for
linear runs')),
] + templateopts,
_('hg glog [OPTION]... [FILE]')),
# "debuggraph": (debugnodegraph, [], ''),
More information about the Mercurial
mailing list