##// END OF EJS Templates
Unified DAG generation for hg and git...
marcink -
r2380:0c7dc340 beta
parent child Browse files
Show More
@@ -0,0 +1,127 b''
1 """
2 Modified mercurial DAG graph functions that re-uses VCS structure
3
4 It allows to have a shared codebase for DAG generation for hg and git repos
5 """
6
7 nullrev = -1
8
9
10 def grandparent(parentrev_func, lowestrev, roots, head):
11 """
12 Return all ancestors of head in roots which revision is
13 greater or equal to lowestrev.
14 """
15 pending = set([head])
16 seen = set()
17 kept = set()
18 llowestrev = max(nullrev, lowestrev)
19 while pending:
20 r = pending.pop()
21 if r >= llowestrev and r not in seen:
22 if r in roots:
23 kept.add(r)
24 else:
25 pending.update([p for p in parentrev_func(r)])
26 seen.add(r)
27 return sorted(kept)
28
29
30 def _dagwalker(repo, revs, alias):
31 if not revs:
32 return
33
34 if alias == 'hg':
35 cl = repo._repo.changelog.parentrevs
36 repo = repo
37 elif alias == 'git':
38 def cl(rev):
39 return [x.revision for x in repo[rev].parents()]
40 repo = repo
41
42 lowestrev = min(revs)
43 gpcache = {}
44
45 knownrevs = set(revs)
46 for rev in revs:
47 ctx = repo[rev]
48 parents = sorted(set([p.revision for p in ctx.parents
49 if p.revision in knownrevs]))
50 mpars = [p.revision for p in ctx.parents if
51 p.revision != nullrev and p.revision not in parents]
52
53 for mpar in mpars:
54 gp = gpcache.get(mpar)
55 if gp is None:
56 gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
57 if not gp:
58 parents.append(mpar)
59 else:
60 parents.extend(g for g in gp if g not in parents)
61
62 yield (ctx.revision, 'C', ctx, parents)
63
64
65 def _colored(dag):
66 """annotates a DAG with colored edge information
67
68 For each DAG node this function emits tuples::
69
70 (id, type, data, (col, color), [(col, nextcol, color)])
71
72 with the following new elements:
73
74 - Tuple (col, color) with column and color index for the current node
75 - A list of tuples indicating the edges between the current node and its
76 parents.
77 """
78 seen = []
79 colors = {}
80 newcolor = 1
81
82 getconf = lambda rev: {}
83
84 for (cur, type, data, parents) in dag:
85
86 # Compute seen and next
87 if cur not in seen:
88 seen.append(cur) # new head
89 colors[cur] = newcolor
90 newcolor += 1
91
92 col = seen.index(cur)
93 color = colors.pop(cur)
94 next = seen[:]
95
96 # Add parents to next
97 addparents = [p for p in parents if p not in next]
98 next[col:col + 1] = addparents
99
100 # Set colors for the parents
101 for i, p in enumerate(addparents):
102 if not i:
103 colors[p] = color
104 else:
105 colors[p] = newcolor
106 newcolor += 1
107
108 # Add edges to the graph
109 edges = []
110 for ecol, eid in enumerate(seen):
111 if eid in next:
112 bconf = getconf(eid)
113 edges.append((
114 ecol, next.index(eid), colors[eid],
115 bconf.get('width', -1),
116 bconf.get('color', '')))
117 elif eid == cur:
118 for p in parents:
119 bconf = getconf(p)
120 edges.append((
121 ecol, next.index(p), color,
122 bconf.get('width', -1),
123 bconf.get('color', '')))
124
125 # Yield and move on
126 yield (cur, type, data, (col, color), edges)
127 seen = next
@@ -26,7 +26,6 b''
26 26 import logging
27 27 import traceback
28 28
29 from mercurial import graphmod
30 29 from pylons import request, url, session, tmpl_context as c
31 30 from pylons.controllers.util import redirect
32 31 from pylons.i18n.translation import _
@@ -36,7 +35,7 b' from rhodecode.lib.auth import LoginRequ'
36 35 from rhodecode.lib.base import BaseRepoController, render
37 36 from rhodecode.lib.helpers import RepoPage
38 37 from rhodecode.lib.compat import json
39
38 from rhodecode.lib.graphmod import _colored, _dagwalker
40 39 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError
41 40
42 41 log = logging.getLogger(__name__)
@@ -117,18 +116,9 b' class ChangelogController(BaseRepoContro'
117 116 data = []
118 117 revs = [x.revision for x in collection]
119 118
120 if repo.alias == 'git':
121 for _ in revs:
122 vtx = [0, 1]
123 edges = [[0, 0, 1]]
124 data.append(['', vtx, edges])
125
126 elif repo.alias == 'hg':
127 dag = graphmod.dagwalker(repo._repo, revs)
128 c.dag = graphmod.colored(dag, repo._repo)
129 for (id, type, ctx, vtx, edges) in c.dag:
130 if type != graphmod.CHANGESET:
131 continue
119 dag = _dagwalker(repo, revs, repo.alias)
120 dag = _colored(dag)
121 for (id, type, ctx, vtx, edges) in dag:
132 122 data.append(['', vtx, edges])
133 123
134 124 c.jsdata = json.dumps(data)
General Comments 0
You need to be logged in to leave comments. Login now