mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 15:57:43 +03:00
fd55ac9c4d
Changes graph() to colorededges(), which operates on the new generic DAG walks and adds color and edge information needed by the web graph. This is in preparation of adding DAG walk filters, like the linear run collapser in the next patch. The idea is to have a bunch of changelog walkers that return basic data. Then we can filter this data. Finally we add edge and formatting info suitable for the output media we want to target (glog, hgweb).
120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
# Revision graph generator for Mercurial
|
|
#
|
|
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
|
|
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2, incorporated herein by reference.
|
|
|
|
"""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'
|
|
|
|
def revisions(repo, start, stop):
|
|
"""cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
|
|
|
|
This generator function walks through the revision history from revision
|
|
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.
|
|
"""
|
|
cur = start
|
|
while cur >= stop:
|
|
ctx = repo[cur]
|
|
parents = [p.rev() for p in ctx.parents() if p.rev() != nullrev]
|
|
yield (cur, CHANGESET, ctx, sorted(parents))
|
|
cur -= 1
|
|
|
|
def filerevs(repo, path, start, stop):
|
|
"""file cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
|
|
|
|
This generator function walks through the revision history of a single
|
|
file from revision start down to revision stop.
|
|
"""
|
|
filerev = len(repo.file(path)) - 1
|
|
while filerev >= 0:
|
|
fctx = repo.filectx(path, fileid=filerev)
|
|
parents = [f.linkrev() for f in fctx.parents() if f.path() == path]
|
|
rev = fctx.rev()
|
|
if rev <= start:
|
|
yield (rev, CHANGESET, fctx, sorted(parents))
|
|
if rev <= stop:
|
|
break
|
|
filerev -= 1
|
|
|
|
def nodes(repo, nodes):
|
|
"""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.
|
|
"""
|
|
include = set(nodes)
|
|
for node in nodes:
|
|
ctx = repo[node]
|
|
parents = [p.rev() for p in ctx.parents() if p.node() in include]
|
|
yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
|
|
|
|
def colored(dag):
|
|
"""annotates a DAG with colored edge information
|
|
|
|
For each DAG node this function emits tuples::
|
|
|
|
(id, type, data, (col, color), [(col, nextcol, color)])
|
|
|
|
with the following new elements:
|
|
|
|
- Tuple (col, color) with column and color index for the current node
|
|
- A list of tuples indicating the edges between the current node and its
|
|
parents.
|
|
"""
|
|
seen = []
|
|
colors = {}
|
|
newcolor = 1
|
|
for (cur, type, data, parents) in dag:
|
|
|
|
# Compute seen and next
|
|
if cur not in seen:
|
|
seen.append(cur) # new head
|
|
colors[cur] = newcolor
|
|
newcolor += 1
|
|
|
|
col = seen.index(cur)
|
|
color = colors.pop(cur)
|
|
next = seen[:]
|
|
|
|
# Add parents to next
|
|
addparents = [p for p in parents if p not in next]
|
|
next[col:col + 1] = addparents
|
|
|
|
# Set colors for the parents
|
|
for i, p in enumerate(addparents):
|
|
if not i:
|
|
colors[p] = color
|
|
else:
|
|
colors[p] = newcolor
|
|
newcolor += 1
|
|
|
|
# Add edges to the graph
|
|
edges = []
|
|
for ecol, eid in enumerate(seen):
|
|
if eid in next:
|
|
edges.append((ecol, next.index(eid), colors[eid]))
|
|
elif eid == cur:
|
|
for p in parents:
|
|
edges.append((ecol, next.index(p), colors[p]))
|
|
|
|
# Yield and move on
|
|
yield (cur, type, data, (col, color), edges)
|
|
seen = next
|