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