Mercurial > hg
changeset 28376:fa2cd0c9a567
graphmod: augment the graph to include more information about the edges
The walker knows when an edge leads to a direct parent, a grandparent (skipping
revisions not part of the revset) and parents that are missing altogether
(neither it nor a grandparent is in the revset). Add this information to the
parents sequence yielded.
author | Martijn Pieters <mjpieters@fb.com> |
---|---|
date | Fri, 04 Mar 2016 14:44:32 +0000 |
parents | 97cb1aeaca78 |
children | 81ad683278b8 |
files | mercurial/graphmod.py |
diffstat | 1 files changed, 28 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/graphmod.py Fri Mar 04 14:44:32 2016 +0000 +++ b/mercurial/graphmod.py Fri Mar 04 14:44:32 2016 +0000 @@ -28,6 +28,9 @@ ) CHANGESET = 'C' +PARENT = 'P' +GRANDPARENT = 'G' +MISSINGPARENT = 'M' def groupbranchiter(revs, parentsfunc, firstbranch=()): """Yield revisions from heads to roots one (topo) branch at a time. @@ -228,12 +231,16 @@ yield r def dagwalker(repo, revs): - """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples + """cset DAG generator yielding (id, CHANGESET, ctx, [parentinfo]) tuples This generator function walks through revisions (which should be ordered - from bigger to lower). 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 + from bigger to lower). It returns a tuple for each node. + + Each parentinfo entry is a tuple with (edgetype, parentid), where edgetype + is one of PARENT, GRANDPARENT or MISSINGPARENT. The node and parent ids + are arbitrary integers which identify a node in the context of the graph returned. + """ if not revs: return @@ -252,10 +259,13 @@ for rev in revs: ctx = repo[rev] - parents = sorted(set([p.rev() for p in ctx.parents() - if p.rev() in revs])) - mpars = [p.rev() for p in ctx.parents() if - p.rev() != nullrev and p.rev() not in parents] + # partition into parents in the rev set and missing parents, then + # augment the lists with markers, to inform graph drawing code about + # what kind of edge to draw between nodes. + pset = set(p.rev() for p in ctx.parents() if p.rev() in revs) + mpars = [p.rev() for p in ctx.parents() + if p.rev() != nullrev and p.rev() not in pset] + parents = [(PARENT, p) for p in sorted(pset)] for mpar in mpars: gp = gpcache.get(mpar) @@ -264,11 +274,14 @@ # through all revs (issue4782) if not isinstance(revs, revset.baseset): revs = revset.baseset(revs) - gp = gpcache[mpar] = revset.reachableroots(repo, revs, [mpar]) + gp = gpcache[mpar] = sorted(set(revset.reachableroots( + repo, revs, [mpar]))) if not gp: - parents.append(mpar) + parents.append((MISSINGPARENT, mpar)) + pset.add(mpar) else: - parents.extend(g for g in gp if g not in parents) + parents.extend((GRANDPARENT, g) for g in gp if g not in pset) + pset.update(gp) yield (ctx.rev(), CHANGESET, ctx, parents) @@ -281,7 +294,8 @@ include = set(nodes) for node in nodes: ctx = repo[node] - parents = set([p.rev() for p in ctx.parents() if p.node() in include]) + parents = set((PARENT, p.rev()) for p in ctx.parents() + if p.node() in include) yield (ctx.rev(), CHANGESET, ctx, sorted(parents)) def colored(dag, repo): @@ -330,7 +344,7 @@ next = seen[:] # Add parents to next - addparents = [p for p in parents if p not in next] + addparents = [p for pt, p in parents if p not in next] next[col:col + 1] = addparents # Set colors for the parents @@ -351,7 +365,7 @@ bconf.get('width', -1), bconf.get('color', ''))) elif eid == cur: - for p in parents: + for ptype, p in parents: bconf = getconf(p) edges.append(( ecol, next.index(p), color, @@ -371,7 +385,7 @@ knownparents = [] newparents = [] - for parent in parents: + for ptype, parent in parents: if parent in seen: knownparents.append(parent) else: