[PATCH 4 of 5] glog: add --collapse-linear or -c option for branching overview
Peter Arrenbrecht
peter.arrenbrecht at gmail.com
Tue Mar 10 15:30:22 CDT 2009
# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1236716760 -3600
glog: add --collapse-linear or -c option for branching overview
This can be used to get an overview of branching and merging in a repo.
It collapses linear runs of nodes, listing only the first <n> nodes of
such runs. For example:
$ hg glog -c1
@ (22) four
|
. ... (2 skipped)
|
| o (19) three
| |
| . ... (4 skipped)
| |
| o (14) merge
| |\
| | o (13) two
| | |
| | . ... (3 skipped)
| | |
| o | (9) one
| | |
| . | ... (3 skipped)
| |/
| o (5) branch
| |
diff --git a/hgext/graphlog.py b/hgext/graphlog.py
--- a/hgext/graphlog.py
+++ b/hgext/graphlog.py
@@ -12,6 +12,7 @@
'''
import os, sys
+from itertools import islice
from mercurial.cmdutil import revrange, show_changeset
from mercurial.commands import templateopts
from mercurial.i18n import _
@@ -31,6 +32,11 @@
lines = displayer.hunk.pop(ctx.rev()).split('\n')[:-1]
char = ctx.node() in showparents and '@' or 'o'
yield (id, ASCIIDATA, (char, lines), parentids)
+ elif type == graphmod.ELISION:
+ skipped = ctx
+ lines = [_('... (%i skipped)') % skipped]
+ char = '.'
+ yield (id, ASCIIDATA, (char, lines), parentids)
def asciiedges(nodes):
"""adds edge info to changelog DAG walk suitable for ascii()"""
@@ -231,6 +237,18 @@
if op in opts and opts[op]:
raise util.Abort(_("--graph option is incompatible with --%s") % op)
+def getlimit(limit):
+ """get a limit from an option value"""
+ if limit:
+ try:
+ limit = int(limit)
+ except ValueError:
+ raise util.Abort(_('limit must be a positive integer'))
+ if limit <= 0: raise util.Abort(_('limit must be positive'))
+ else:
+ limit = sys.maxint
+ return limit
+
def graphlog(ui, repo, path=None, **opts):
"""show revision history alongside an ASCII revision graph
@@ -243,8 +261,10 @@
check_unsupported_flags(opts)
limit = cmdutil.loglimit(opts)
+ collapse = getlimit(opts["collapse_linear"])
start, stop = get_revs(repo, opts["rev"])
- stop = max(stop, start - limit + 1)
+ if collapse == sys.maxint:
+ stop = max(stop, start - limit + 1)
if start == nullrev:
return
@@ -255,15 +275,16 @@
else:
revdag = graphmod.changelogwalk(repo, start, stop)
+ if collapse < sys.maxint:
+ revdag = islice(graphmod.collapseruns(revdag, collapse), limit)
+
fmtdag = asciiformat(ui, repo, revdag, opts)
ascii(ui, asciiedges(fmtdag))
def graphrevs(repo, nodes, opts):
nodes.reverse()
limit = cmdutil.loglimit(opts)
- if limit < sys.maxint:
- nodes = nodes[:limit]
- return graphmod.nodelistwalk(repo, nodes)
+ return islice(graphmod.nodelistwalk(repo, nodes), limit)
def goutgoing(ui, repo, dest=None, **opts):
"""show the outgoing changesets alongside an ASCII revision graph
@@ -372,6 +393,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]')),
}
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -12,7 +12,7 @@
(id, type, data, [parentids])
-The node and parent ids are arbitrary integers which identify a node in the
+The node and parent ids are arbitrary values which identify a node in the
context of the graph returned. Type is a constant specifying the node type.
Data depends on type.
"""
@@ -21,6 +21,7 @@
import util
CHANGESET = 'C'
+ELISION = 'E'
def changelogwalk(repo, start, stop):
"""cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
@@ -69,6 +70,72 @@
parents = [p.rev() for p in ctx.parents() if p.node() in include]
yield (ctx.rev(), CHANGESET, ctx, parents)
+def collapseruns(dag, runslongerthan):
+ """cset DAG transformer which collapses linear runs of nodes"""
+ expecting = {}
+ def expect(id, parents):
+ for p in parents:
+ if not expecting.get(p):
+ expecting[p] = id
+
+ skipfirstid = None
+ skipfirsttype = None
+ skipfirstdata = None
+ skiplastparents = []
+ skiplen = 0
+ runlen = 0
+ previd = None
+ prevloneparentid = None
+ for (id, type, data, parents) in dag:
+ skip = False
+ expectedby = expecting.get(id)
+ if expectedby:
+ del expecting[id]
+ if len(parents) > 1:
+ prevloneparentid = None
+ else:
+ skip = (id == prevloneparentid
+ and (not expectedby or expectedby == previd))
+ if len(parents) > 0:
+ prevloneparentid = parents[0]
+ else:
+ prevloneparentid = None
+ if skip:
+ if skipfirstid:
+ skiplastparents = parents
+ skiplen += 1
+ else:
+ runlen += 1
+ if runlen >= runslongerthan:
+ skipfirstid = id
+ skipfirsttype = type
+ skipfirstdata = data
+ skiplastparents = parents
+ skiplen = 1
+ else:
+ runlen = 0
+ if skipfirstid:
+ if skiplen >= 2:
+ yield (skipfirstid, ELISION, skiplen, skiplastparents)
+ else:
+ yield (skipfirstid, skipfirsttype, skipfirstdata,
+ skiplastparents)
+ expect(skipfirstid, skiplastparents)
+ skipfirstid = None
+ if not skipfirstid:
+ yield (id, type, data, parents)
+ expect(id, parents)
+ previd = id
+
+ # final
+ if skipfirstid:
+ if skiplen >= 2:
+ yield (skipfirstid, ELISION, skiplen, skiplastparents)
+ else:
+ yield (skipfirstid, skipfirsttype, skipfirstdata,
+ skiplastparents)
+
+
def colorededges(dag):
"""annotates a DAG with colored edge information
diff --git a/tests/test-glog b/tests/test-glog
--- a/tests/test-glog
+++ b/tests/test-glog
@@ -173,3 +173,44 @@
hg incoming -q --graph | sed -e 's|$HGTMP|[HGTMP]|'
cd ..
hg -R repo outgoing --graph repo2
+
+echo % collapse linear runs
+hg init runs
+cd runs
+echo % building tree with runs
+commit 0 "root"
+commit 1 "run" 0
+commit 2 "run" 1
+commit 3 "run" 2
+commit 4 "run" 3
+commit 5 "branch" 4
+commit 6 "one" 5
+commit 7 "one" 6
+commit 8 "one" 7
+commit 9 "one" 8
+commit 10 "two" 5
+commit 11 "two" 10
+commit 12 "two" 11
+commit 13 "two" 12
+commit 14 "merge" 9 13
+commit 15 "three" 14
+commit 16 "three" 15
+commit 17 "three" 16
+commit 18 "three" 17
+commit 19 "three" 18
+commit 20 "four" 3
+commit 21 "four" 20
+commit 22 "four" 21
+echo % unfiltered
+hg glog --template "{desc}\n"
+echo % c1
+hg glog -c1 --template "{desc}\n"
+echo % c2
+hg glog -c2 --template "{desc}\n"
+echo % c3
+hg glog -c3 --template "{desc}\n"
+echo % c4
+hg glog -c4 --template "{desc}\n"
+echo % c1 l10
+hg glog -c1 -l10 --template "{desc}\n"
+
diff --git a/tests/test-glog.out b/tests/test-glog.out
--- a/tests/test-glog.out
+++ b/tests/test-glog.out
@@ -423,3 +423,252 @@
date: Thu Jan 01 00:00:27 1970 +0000
summary: (27) collapse
+% collapse linear runs
+% building tree with runs
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+(the rawcommit command is deprecated)
+% unfiltered
+@ (22) four
+|
+o (21) four
+|
+o (20) four
+|
+| o (19) three
+| |
+| o (18) three
+| |
+| o (17) three
+| |
+| o (16) three
+| |
+| o (15) three
+| |
+| o (14) merge
+| |\
+| | o (13) two
+| | |
+| | o (12) two
+| | |
+| | o (11) two
+| | |
+| | o (10) two
+| | |
+| o | (9) one
+| | |
+| o | (8) one
+| | |
+| o | (7) one
+| | |
+| o | (6) one
+| |/
+| o (5) branch
+| |
+| o (4) run
+|/
+o (3) run
+|
+o (2) run
+|
+o (1) run
+|
+o (0) root
+
+% c1
+@ (22) four
+|
+. ... (2 skipped)
+|
+| o (19) three
+| |
+| . ... (4 skipped)
+| |
+| o (14) merge
+| |\
+| | o (13) two
+| | |
+| | . ... (3 skipped)
+| | |
+| o | (9) one
+| | |
+| . | ... (3 skipped)
+| |/
+| o (5) branch
+| |
+| o (4) run
+|/
+o (3) run
+|
+. ... (3 skipped)
+
+% c2
+@ (22) four
+|
+o (21) four
+|
+o (20) four
+|
+| o (19) three
+| |
+| o (18) three
+| |
+| . ... (3 skipped)
+| |
+| o (14) merge
+| |\
+| | o (13) two
+| | |
+| | o (12) two
+| | |
+| | . ... (2 skipped)
+| | |
+| o | (9) one
+| | |
+| o | (8) one
+| | |
+| . | ... (2 skipped)
+| |/
+| o (5) branch
+| |
+| o (4) run
+|/
+o (3) run
+|
+o (2) run
+|
+. ... (2 skipped)
+
+% c3
+@ (22) four
+|
+o (21) four
+|
+o (20) four
+|
+| o (19) three
+| |
+| o (18) three
+| |
+| o (17) three
+| |
+| . ... (2 skipped)
+| |
+| o (14) merge
+| |\
+| | o (13) two
+| | |
+| | o (12) two
+| | |
+| | o (11) two
+| | |
+| | o (10) two
+| | |
+| o | (9) one
+| | |
+| o | (8) one
+| | |
+| o | (7) one
+| | |
+| o | (6) one
+| |/
+| o (5) branch
+| |
+| o (4) run
+|/
+o (3) run
+|
+o (2) run
+|
+o (1) run
+|
+o (0) root
+
+% c4
+@ (22) four
+|
+o (21) four
+|
+o (20) four
+|
+| o (19) three
+| |
+| o (18) three
+| |
+| o (17) three
+| |
+| o (16) three
+| |
+| o (15) three
+| |
+| o (14) merge
+| |\
+| | o (13) two
+| | |
+| | o (12) two
+| | |
+| | o (11) two
+| | |
+| | o (10) two
+| | |
+| o | (9) one
+| | |
+| o | (8) one
+| | |
+| o | (7) one
+| | |
+| o | (6) one
+| |/
+| o (5) branch
+| |
+| o (4) run
+|/
+o (3) run
+|
+o (2) run
+|
+o (1) run
+|
+o (0) root
+
+% c1 l10
+@ (22) four
+|
+. ... (2 skipped)
+|
+| o (19) three
+| |
+| . ... (4 skipped)
+| |
+| o (14) merge
+| |\
+| | o (13) two
+| | |
+| | . ... (3 skipped)
+| | |
+| o | (9) one
+| | |
+| . | ... (3 skipped)
+| |/
+| o (5) branch
+| |
More information about the Mercurial-devel
mailing list