##// END OF EJS Templates
Merge with stable
Merge with stable

File last commit:

r10111:27457d31 default
r10187:fcc15ba1 merge default
Show More
graphmod.py
122 lines | 3.9 KiB | text/x-python | PythonLexer
Dirkjan Ochtman
add graph page to hgweb
r6691 # Revision graph generator for Mercurial
#
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
# GNU General Public License version 2, incorporated herein by reference.
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """supports walking the history as DAGs suitable for graphical output
The most basic format we use is that of::
(id, type, data, [parentids])
The node and parent ids are arbitrary integers which identify a node in the
context of the graph returned. Type is a constant specifying the node type.
Data depends on type.
"""
from mercurial.node import nullrev
CHANGESET = 'C'
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 def revisions(repo, start, stop):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836
This generator function walks through the revision history from revision
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 start to revision stop (which must be less than or equal to start). It
returns a tuple for each node. The node and parent ids are arbitrary
integers which identify a node in the context of the graph returned.
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 """
cur = start
while cur >= stop:
ctx = repo[cur]
parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev]
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 yield (cur, CHANGESET, ctx, sorted(parents))
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 cur -= 1
Nicolas Dumazet
cmdutil: replace sys.maxint with None as default value in loglimit...
r10111 def filerevs(repo, path, start, stop, limit=None):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836
This generator function walks through the revision history of a single
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 file from revision start down to revision stop.
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 """
filerev = len(repo.file(path)) - 1
Nicolas Dumazet
graphlog: fix output when both a limit and a path are provided...
r10084 rev = stop + 1
count = 0
while filerev >= 0 and rev > stop:
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 fctx = repo.filectx(path, fileid=filerev)
parents = [f.linkrev() for f in fctx.parents() if f.path() == path]
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 rev = fctx.rev()
if rev <= start:
Dirkjan Ochtman
graphlog: don't pass filectxs to the templater (issue1896)
r9727 yield (rev, CHANGESET, fctx.changectx(), sorted(parents))
Nicolas Dumazet
graphlog: fix output when both a limit and a path are provided...
r10084 count += 1
if count == limit:
break
Peter Arrenbrecht
graphmod/graphlog: move log walks to graphmod
r8836 filerev -= 1
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837 def nodes(repo, nodes):
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
This generator function walks the given nodes. It only returns parents
that are in nodes, too.
"""
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837 include = set(nodes)
for node in nodes:
ctx = repo[node]
parents = [p.rev() for p in ctx.parents() if p.node() in include]
Peter Arrenbrecht
graphmod/graphlog: make dag walks carry data as type, payload
r8840 yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
Peter Arrenbrecht
graphmod/graphlog: extract nodelistwalk
r8837
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 def colored(dag):
"""annotates a DAG with colored edge information
For each DAG node this function emits tuples::
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 (id, type, data, (col, color), [(col, nextcol, color)])
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 with the following new elements:
Peter Arrenbrecht
graphmod: code cleanup and doc fix
r8835 - Tuple (col, color) with column and color index for the current node
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 - A list of tuples indicating the edges between the current node and its
parents.
Dirkjan Ochtman
add graph page to hgweb
r6691 """
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 seen = []
Dirkjan Ochtman
add graph page to hgweb
r6691 colors = {}
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 newcolor = 1
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 for (cur, type, data, parents) in dag:
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 # Compute seen and next
if cur not in seen:
seen.append(cur) # new head
colors[cur] = newcolor
newcolor += 1
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 col = seen.index(cur)
color = colors.pop(cur)
next = seen[:]
Dirkjan Ochtman
add graph page to hgweb
r6691
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 # Add parents to next
Dirkjan Ochtman
add graph page to hgweb
r6691 addparents = [p for p in parents if p not in next]
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 next[col:col + 1] = addparents
Dirkjan Ochtman
add graph page to hgweb
r6691
# Set colors for the parents
for i, p in enumerate(addparents):
if not i:
colors[p] = color
else:
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 colors[p] = newcolor
newcolor += 1
Dirkjan Ochtman
add graph page to hgweb
r6691
# Add edges to the graph
edges = []
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 for ecol, eid in enumerate(seen):
if eid in next:
edges.append((ecol, next.index(eid), colors[eid]))
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 elif eid == cur:
Dirkjan Ochtman
add graph page to hgweb
r6691 for p in parents:
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 edges.append((ecol, next.index(p), colors[p]))
Dirkjan Ochtman
add graph page to hgweb
r6691
# Yield and move on
Peter Arrenbrecht
graphmod/webcommands: use generic DAG walks...
r8842 yield (cur, type, data, (col, color), edges)
Peter Arrenbrecht
graphmod: rename a bunch of vars in graph()
r8841 seen = next