[PATCH 2 of 4 V2] graphmod: augment the graph to include more information about the edges

Augie Fackler raf at durin42.com
Mon Mar 7 22:24:24 EST 2016


On Fri, Mar 04, 2016 at 08:47:04PM +0000, Martijn Pieters wrote:
> # HG changeset patch
> # User Martijn Pieters <mjpieters at fb.com>
> # Date 1457102672 0
> #      Fri Mar 04 14:44:32 2016 +0000
> # Node ID ddeb44b0971f0c34b23f5f541c5d9a0b8c6c5892
> # Parent  bff91cf405daabda16b110bb76f1949f562d607b
> graphmod: augment the graph to include more information about the edges

First two are queued, I need to look at patch 3 when I have more
time. Please remind me if you don't hear back tomorrow.

>
> 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.
>
> diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
> --- a/mercurial/graphmod.py
> +++ b/mercurial/graphmod.py
> @@ -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:
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list