Merge lp:~mwhudson/loggerhead/iter_changes-forevar into lp:loggerhead

Proposed by Michael Hudson-Doyle
Status: Merged
Merged at revision: not available
Proposed branch: lp:~mwhudson/loggerhead/iter_changes-forevar
Merge into: lp:loggerhead
Diff against target: None lines
To merge this branch: bzr merge lp:~mwhudson/loggerhead/iter_changes-forevar
Reviewer Review Type Date Requested Status
Martin Albisetti Approve
Review via email: mp+4644@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

The goal of this branch, as the name suggests, wass to start using iter_changes() directly to find changes between trees rather than the inherently wrong-scaling changes_from(). It will probably perform better on chk repos, but not noticeably differently on packs.

However, the bulk of the diff is actually making the history interface significantly simpler given that no single page load in loggerhead considers the difference between more than two revisions -- before ajaxy-changelog landed, the changelog view computed many many deltas. This makes a bunch of interfaces clearer.

319. By Michael Hudson-Doyle

oops

320. By Michael Hudson-Doyle

grr

Revision history for this message
Martin Albisetti (beuno) wrote :

Hi Michael,

This looks great, and very nice usage of change reporter.
Do we have enough test coverage around these areas? I expect we do since this affects almost everything, but I thought I'd ask anyway :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'loggerhead/changecache.py'
2--- loggerhead/changecache.py 2008-10-24 02:26:05 +0000
3+++ loggerhead/changecache.py 2009-03-18 20:57:19 +0000
4@@ -70,11 +70,10 @@
5 else:
6 return self._unserialize(filechange[0])
7
8- def add(self, revid_obj_pairs):
9- for (r, d) in revid_obj_pairs:
10- self.cursor.execute(
11- "insert into revisiondata (revid, data) values (?, ?)",
12- (r, self._serialize(d)))
13+ def add(self, revid, object):
14+ self.cursor.execute(
15+ "insert into revisiondata (revid, data) values (?, ?)",
16+ (revid, self._serialize(object)))
17 self.connection.commit()
18
19
20@@ -93,26 +92,10 @@
21 self._lock = LockFile(os.path.join(cache_path, 'filechange-lock'))
22
23 @with_lock
24- def get_file_changes(self, entries):
25- out = []
26- missing_entries = []
27- missing_entry_indices = []
28+ def get_file_changes(self, entry):
29 cache = FakeShelf(self._changes_filename)
30- for entry in entries:
31- changes = cache.get(entry.revid)
32- if changes is not None:
33- out.append(changes)
34- else:
35- missing_entries.append(entry)
36- missing_entry_indices.append(len(out))
37- out.append(None)
38- if missing_entries:
39- missing_changes = self.history.get_file_changes_uncached(
40- missing_entries)
41- revid_changes_pairs = []
42- for i, entry, changes in zip(
43- missing_entry_indices, missing_entries, missing_changes):
44- revid_changes_pairs.append((entry.revid, changes))
45- out[i] = changes
46- cache.add(revid_changes_pairs)
47- return out
48+ changes = cache.get(entry.revid)
49+ if changes is None:
50+ changes = self.history.get_file_changes_uncached(entry)
51+ cache.add(entry.revid, changes)
52+ return changes
53
54=== modified file 'loggerhead/controllers/inventory_ui.py'
55--- loggerhead/controllers/inventory_ui.py 2009-03-03 20:43:12 +0000
56+++ loggerhead/controllers/inventory_ui.py 2009-03-19 00:44:05 +0000
57@@ -146,8 +146,7 @@
58 revno_url = 'head:'
59 else:
60 revno_url = history.get_revno(revid)
61- # add parent & merge-point branch-nick info, in case it's useful
62- history.get_branch_nicks([ change ])
63+ history.add_branch_nicks(change)
64
65 # Create breadcrumb trail for the path within the branch
66 branch_breadcrumbs = util.branch_breadcrumbs(path, rev_tree, 'files')
67
68=== modified file 'loggerhead/controllers/revision_ui.py'
69--- loggerhead/controllers/revision_ui.py 2009-03-18 04:54:35 +0000
70+++ loggerhead/controllers/revision_ui.py 2009-03-19 00:44:05 +0000
71@@ -28,7 +28,6 @@
72 from loggerhead import util
73 from loggerhead.controllers import TemplatedBranchView
74 from loggerhead.controllers.filediff_ui import diff_chunks_for_file
75-from loggerhead.history import rich_filename
76
77
78 DEFAULT_LINE_COUNT_LIMIT = 3000
79@@ -36,77 +35,11 @@
80 def dq(p):
81 return urllib.quote(urllib.quote(p, safe=''))
82
83+
84 class RevisionUI(TemplatedBranchView):
85
86 template_path = 'loggerhead.templates.revision'
87
88- def _parse_diffs(self, old_tree, new_tree, delta, specific_path):
89- """
90- Return a list of processed diffs, in the format::
91-
92- list(
93- filename: str,
94- file_id: str,
95- chunks: list(
96- diff: list(
97- old_lineno: int,
98- new_lineno: int,
99- type: str('context', 'delete', or 'insert'),
100- line: str,
101- ),
102- ),
103- )
104- """
105- if specific_path:
106- fid = new_tree.path2id(specific_path)
107- kind = new_tree.kind(fid)
108- chunks=diff_chunks_for_file(fid, old_tree, new_tree)
109- return [util.Container(
110- filename=rich_filename(specific_path, kind), file_id=fid,
111- chunks=chunks)]
112-
113- process = []
114- out = []
115-
116- for old_path, new_path, fid, \
117- kind, text_modified, meta_modified in delta.renamed:
118- if text_modified:
119- process.append((new_path, fid, kind))
120- for path, fid, kind, text_modified, meta_modified in delta.modified:
121- process.append((path, fid, kind))
122- for path, fid, kind in delta.added:
123- if kind == 'file':
124- process.append((path, fid, kind))
125- for path, fid, kind in delta.removed:
126- if kind == 'file':
127- process.append((path, fid, kind))
128-
129- process.sort()
130-
131- for new_path, fid, kind in process:
132- out.append(util.Container(
133- filename=rich_filename(new_path, kind), file_id=fid,
134- chunks=[]))
135-
136- return out
137-
138- def get_changes_with_diff(self, change, compare_revid, specific_path):
139- h = self._history
140- if compare_revid is None:
141- if change.parents:
142- compare_revid = change.parents[0].revid
143- else:
144- compare_revid = 'null:'
145-
146- rev_tree1 = h._branch.repository.revision_tree(compare_revid)
147- rev_tree2 = h._branch.repository.revision_tree(change.revid)
148- delta = rev_tree2.changes_from(rev_tree1)
149-
150- changes = h.parse_delta(delta)
151-
152- return changes, self._parse_diffs(
153- rev_tree1, rev_tree2, delta, specific_path)
154-
155 def get_values(self, path, kwargs, headers):
156 h = self._history
157 revid = self.get_revid()
158@@ -135,25 +68,37 @@
159 util.fill_in_navigation(navigation)
160
161 change = h.get_changes([revid])[0]
162+
163+ if compare_revid is None:
164+ if change.parents:
165+ cr = change.parents[0].revid
166+ else:
167+ cr = 'null:'
168+ else:
169+ cr = compare_revid
170+
171 if path in ('', '/'):
172 path = None
173- change.changes, diffs = self.get_changes_with_diff(change, compare_revid, path)
174+
175+ old_tree = h._branch.repository.revision_tree(cr)
176+ new_tree = h._branch.repository.revision_tree(change.revid)
177+ file_changes = h.file_changes_from_revision_trees(
178+ old_tree, new_tree)
179+
180 link_data = {}
181 path_to_id = {}
182- if compare_revid is None:
183- if change.parents:
184- cr = change.parents[0].revid
185- else:
186- cr = 'null:'
187+ if path:
188+ diff_chunks = diff_chunks_for_file(
189+ new_tree.path2id(path), old_tree, new_tree)
190 else:
191- cr = compare_revid
192- for i, item in enumerate(diffs):
193- item.index = i
194- link_data['diff-' + str(i)] = '%s/%s/%s' % (
195- dq(revid), dq(cr), dq(item.file_id))
196- path_to_id[item.filename] = 'diff-' + str(i)
197- # add parent & merge-point branch-nick info, in case it's useful
198- h.get_branch_nicks([change])
199+ diff_chunks = None
200+ for i, item in enumerate(file_changes.text_changes):
201+ item.index = i
202+ link_data['diff-' + str(i)] = '%s/%s/%s' % (
203+ dq(revid), dq(cr), dq(item.file_id))
204+ path_to_id[item.filename] = 'diff-' + str(i)
205+
206+ h.add_branch_nicks(change)
207
208 # Directory Breadcrumbs
209 directory_breadcrumbs = (
210@@ -166,7 +111,8 @@
211 'branch': self._branch,
212 'revid': revid,
213 'change': change,
214- 'diffs': diffs,
215+ 'file_changes': file_changes,
216+ 'diff_chunks': diff_chunks,
217 'link_data': simplejson.dumps(link_data),
218 'specific_path': path,
219 'json_specific_path': simplejson.dumps(path),
220
221=== modified file 'loggerhead/controllers/revlog_ui.py'
222--- loggerhead/controllers/revlog_ui.py 2009-03-16 23:01:40 +0000
223+++ loggerhead/controllers/revlog_ui.py 2009-03-19 00:44:05 +0000
224@@ -13,13 +13,14 @@
225
226 revid = urllib.unquote(self.args[0])
227
228- changes = list(history.get_changes([revid]))
229- history.add_changes(changes)
230- history.get_branch_nicks(changes)
231+ change = history.get_changes([revid])[0]
232+ file_changes = history.get_file_changes(change)
233+ history.add_branch_nicks(change)
234
235 return {
236 'branch': self._branch,
237- 'entry': changes[0],
238+ 'entry': change,
239+ 'file_changes': file_changes,
240 'util': util,
241 'revid': revid,
242 'url': self._branch.context_url,
243
244=== modified file 'loggerhead/history.py'
245--- loggerhead/history.py 2009-03-16 23:21:29 +0000
246+++ loggerhead/history.py 2009-03-19 00:44:05 +0000
247@@ -44,6 +44,7 @@
248
249 import bzrlib
250 import bzrlib.branch
251+import bzrlib.delta
252 import bzrlib.diff
253 import bzrlib.errors
254 import bzrlib.progress
255@@ -129,6 +130,38 @@
256 def __len__(self):
257 return len(self.revid_list)
258
259+class FileChangeReporter(object):
260+ def __init__(self):
261+ self.added = []
262+ self.modified = []
263+ self.renamed = []
264+ self.removed = []
265+ self.text_changes = []
266+ def report(self, file_id, paths, versioned, renamed, modified,
267+ exe_change, kind):
268+ if modified not in ('unchanged', 'kind changed'):
269+ self.text_changes.append(util.Container(
270+ filename=rich_filename(paths[1], kind[0]),
271+ file_id=file_id))
272+ if versioned == 'added':
273+ self.added.append(util.Container(
274+ filename=rich_filename(paths[1], kind),
275+ file_id=file_id, kind=kind[1]))
276+ elif versioned == 'removed':
277+ self.removed.append(util.Container(
278+ filename=rich_filename(paths[1], kind),
279+ file_id=file_id, kind=kind[0]))
280+ elif renamed:
281+ self.renamed.append(util.Container(
282+ old_filename=rich_filename(paths[0], kind[0]),
283+ new_filename=rich_filename(paths[1], kind[1]),
284+ file_id=file_id,
285+ text_modified=modified == 'modified'))
286+ else:
287+ self.modified.append(util.Container(
288+ filename=rich_filename(paths[1], kind),
289+ file_id=file_id))
290+
291
292 class History (object):
293 """Decorate a branch to provide information for rendering.
294@@ -457,31 +490,28 @@
295
296 return [d[revnos][1] for revnos in d.keys()]
297
298- def get_branch_nicks(self, changes):
299+ def add_branch_nicks(self, change):
300 """
301- given a list of changes from L{get_changes}, fill in the branch nicks
302- on all parents and merge points.
303+ given a 'change', fill in the branch nicks on all parents and merge
304+ points.
305 """
306 fetch_set = set()
307- for change in changes:
308- for p in change.parents:
309- fetch_set.add(p.revid)
310- for p in change.merge_points:
311- fetch_set.add(p.revid)
312+ for p in change.parents:
313+ fetch_set.add(p.revid)
314+ for p in change.merge_points:
315+ fetch_set.add(p.revid)
316 p_changes = self.get_changes(list(fetch_set))
317 p_change_dict = dict([(c.revid, c) for c in p_changes])
318- for change in changes:
319- # arch-converted branches may not have merged branch info :(
320- for p in change.parents:
321- if p.revid in p_change_dict:
322- p.branch_nick = p_change_dict[p.revid].branch_nick
323- else:
324- p.branch_nick = '(missing)'
325- for p in change.merge_points:
326- if p.revid in p_change_dict:
327- p.branch_nick = p_change_dict[p.revid].branch_nick
328- else:
329- p.branch_nick = '(missing)'
330+ for p in change.parents:
331+ if p.revid in p_change_dict:
332+ p.branch_nick = p_change_dict[p.revid].branch_nick
333+ else:
334+ p.branch_nick = '(missing)'
335+ for p in change.merge_points:
336+ if p.revid in p_change_dict:
337+ p.branch_nick = p_change_dict[p.revid].branch_nick
338+ else:
339+ p.branch_nick = '(missing)'
340
341 def get_changes(self, revid_list):
342 """Return a list of changes objects for the given revids.
343@@ -526,32 +556,6 @@
344
345 return [self._change_from_revision(rev) for rev in rev_list]
346
347- def _get_deltas_for_revisions_with_trees(self, revisions):
348- """Produce a list of revision deltas.
349-
350- Note that the input is a sequence of REVISIONS, not revision_ids.
351- Trees will be held in memory until the generator exits.
352- Each delta is relative to the revision's lefthand predecessor.
353- (This is copied from bzrlib.)
354- """
355- required_trees = set()
356- for revision in revisions:
357- required_trees.add(revision.revid)
358- required_trees.update([p.revid for p in revision.parents[:1]])
359- trees = dict((t.get_revision_id(), t) for
360- t in self._branch.repository.revision_trees(
361- required_trees))
362- ret = []
363- for revision in revisions:
364- if not revision.parents:
365- old_tree = self._branch.repository.revision_tree(
366- bzrlib.revision.NULL_REVISION)
367- else:
368- old_tree = trees[revision.parents[0].revid]
369- tree = trees[revision.revid]
370- ret.append(tree.changes_from(old_tree))
371- return ret
372-
373 def _change_from_revision(self, revision):
374 """
375 Given a bzrlib Revision, return a processed "change" for use in
376@@ -581,22 +585,24 @@
377 }
378 return util.Container(entry)
379
380- def get_file_changes_uncached(self, entries):
381- delta_list = self._get_deltas_for_revisions_with_trees(entries)
382-
383- return [self.parse_delta(delta) for delta in delta_list]
384-
385- def get_file_changes(self, entries):
386+ def get_file_changes_uncached(self, entry):
387+ repo = self._branch.repository
388+ if entry.parents:
389+ old_tree = repo.revision_tree(entry.parents[0].revid)
390+ else:
391+ old_tree = repo.revision_tree(bzrlib.revision.NULL_REVISION)
392+ new_tree = repo.revision_tree(entry.revid)
393+ return self.file_changes_from_revision_trees(old_tree, new_tree)
394+
395+ def get_file_changes(self, entry):
396 if self._file_change_cache is None:
397- return self.get_file_changes_uncached(entries)
398+ return self.get_file_changes_uncached(entry)
399 else:
400- return self._file_change_cache.get_file_changes(entries)
401-
402- def add_changes(self, entries):
403- changes_list = self.get_file_changes(entries)
404-
405- for entry, changes in zip(entries, changes_list):
406- entry.changes = changes
407+ return self._file_change_cache.get_file_changes(entry)
408+
409+ def add_changes(self, entry):
410+ changes = self.get_file_changes(entry)
411+ entry.changes = changes
412
413 def get_file(self, file_id, revid):
414 "returns (path, filename, data)"
415@@ -608,7 +614,7 @@
416 path = '/' + path
417 return path, inv_entry.name, rev_tree.get_file_text(file_id)
418
419- def parse_delta(self, delta):
420+ def file_changes_from_revision_trees(self, old_tree, new_tree):
421 """
422 Return a nested data structure containing the changes in a delta::
423
424@@ -618,31 +624,16 @@
425 modified: list(
426 filename: str,
427 file_id: str,
428- )
429+ ),
430+ text_changes: list((filename, file_id)),
431 """
432- added = []
433- modified = []
434- renamed = []
435- removed = []
436-
437- for path, fid, kind in delta.added:
438- added.append(util.Container(
439- filename=rich_filename(path, kind), file_id=fid, kind=kind))
440-
441- for path, fid, kind, text_modified, meta_modified in delta.modified:
442- modified.append(util.Container(
443- filename=rich_filename(path, kind), file_id=fid))
444-
445- for old_path, new_path, fid, kind, text_modified, meta_modified in \
446- delta.renamed:
447- renamed.append(util.Container(
448- old_filename=rich_filename(old_path, kind),
449- new_filename=rich_filename(new_path, kind), file_id=fid,
450- text_modified=text_modified))
451-
452- for path, fid, kind in delta.removed:
453- removed.append(util.Container(
454- filename=rich_filename(path, kind), file_id=fid, kind=kind))
455-
456- return util.Container(added=added, renamed=renamed,
457- removed=removed, modified=modified)
458+ reporter = FileChangeReporter()
459+
460+ bzrlib.delta.report_changes(new_tree.iter_changes(old_tree), reporter)
461+
462+ return util.Container(
463+ added=sorted(reporter.added, key=lambda x:x.filename),
464+ renamed=sorted(reporter.renamed, key=lambda x:x.new_filename),
465+ removed=sorted(reporter.removed, key=lambda x:x.filename),
466+ modified=sorted(reporter.modified, key=lambda x:x.filename),
467+ text_changes=sorted(reporter.text_changes))
468
469=== modified file 'loggerhead/static/javascript/diff.js'
470--- loggerhead/static/javascript/diff.js 2009-03-17 06:51:29 +0000
471+++ loggerhead/static/javascript/diff.js 2009-03-18 04:08:41 +0000
472@@ -162,14 +162,16 @@
473 Y.on(
474 "domready", function () {
475 Y.all(".show_if_js").removeClass("show_if_js");
476- Y.all("#list-files a").on(
477- 'click',
478- function (e) {
479- e.preventDefault();
480- var path = decodeURIComponent(e.target.get('href').split('#')[1]);
481- window.location.hash = '#' + path;
482- zoom_to_diff(path);
483- });
484+ if (!specific_path) {
485+ Y.all("#list-files a").on(
486+ 'click',
487+ function (e) {
488+ e.preventDefault();
489+ var path = decodeURIComponent(e.target.get('href').split('#')[1]);
490+ window.location.hash = '#' + path;
491+ zoom_to_diff(path);
492+ });
493+ }
494 var diffs = Y.all('.diff');
495 if (diffs == null) return;
496 diffs.each(
497
498=== modified file 'loggerhead/templatefunctions.py'
499--- loggerhead/templatefunctions.py 2009-03-17 06:32:25 +0000
500+++ loggerhead/templatefunctions.py 2009-03-19 00:18:46 +0000
501@@ -38,7 +38,7 @@
502
503
504 @templatefunc
505-def file_change_summary(url, entry, style='normal', currently_showing=None):
506+def file_change_summary(url, entry, file_changes, style='normal', currently_showing=None):
507 if style == 'fragment':
508 def file_link(filename):
509 if currently_showing and filename == currently_showing:
510@@ -53,16 +53,15 @@
511 url(['/revision', entry.revno]), '#' + filename, cgi.escape(filename),
512 cgi.escape(entry.revno), cgi.escape(filename))
513 return _pt('revisionfilechanges').expand(
514- url=url, entry=entry, file_link=file_link,
515- currently_showing=currently_showing, **templatefunctions)
516+ entry=entry, file_changes=file_changes, file_link=file_link, **templatefunctions)
517
518
519 @templatefunc
520-def revisioninfo(url, branch, entry, include_file_list=False, currently_showing=None):
521+def revisioninfo(url, branch, entry, file_changes=None, currently_showing=None):
522 from loggerhead import util
523 return _pt('revisioninfo').expand(
524 url=url, change=entry, branch=branch, util=util,
525- include_file_list=include_file_list, currently_showing=currently_showing,
526+ file_changes=file_changes, currently_showing=currently_showing,
527 **templatefunctions)
528
529
530
531=== modified file 'loggerhead/templates/revision.pt'
532--- loggerhead/templates/revision.pt 2009-03-17 03:49:33 +0000
533+++ loggerhead/templates/revision.pt 2009-03-19 00:44:05 +0000
534@@ -96,7 +96,7 @@
535 </ul>
536 </tal:we-are-comparing>
537
538- <tal:revision-info replace="structure python:revisioninfo(url, branch, change, 'fragment', specific_path)" />
539+ <tal:revision-info replace="structure python:revisioninfo(url, branch, change, file_changes, specific_path)" />
540 <tal:specific-path condition="not:specific_path">
541 <p class="expand show_if_js" id="expand_all"><a href="#">
542 <img tal:attributes="src python:branch.static_url('/static/images/treeCollapsed.png')"
543@@ -116,62 +116,85 @@
544 </tal:block>
545
546 <div metal:fill-slot="content">
547- <div class="diff"
548- tal:repeat="item diffs" tal:attributes="id string:diff-${item/index}">
549+ <tal:block condition="specific_path">
550+ <div class="diff">
551
552- <div class="diffBox">
553- <a tal:attributes="href python:url(['/revision', change.revno, item.filename], clear=1);
554- id string:${item/filename};
555- title string:View changes to ${item/filename} only"
556- class="the-link">
557- <img tal:attributes="src python:branch.static_url('/static/images/treeCollapsed.png');
558- title python:branch.static_url('/static/images/treeCollapsed.png');
559- alt python:branch.static_url('/static/images/treeExpanded.png')"
560- class="expand_diff" tal:condition="not:specific_path" />
561- <img tal:attributes="src python:branch.static_url('/static/images/treeExpanded.png');
562- title python:branch.static_url('/static/images/treeCollapsed.png');
563- alt python:branch.static_url('/static/images/treeExpanded.png')"
564- class="expand_diff" tal:condition="specific_path" />
565- <tal:b content="item/filename" />
566- </a>
567- </div>
568- <div style="overflow: hidden">
569- <div class="container">
570- <div class="loading" style="display:none">
571- <img tal:attributes="src python:branch.static_url('/static/images/spinner.gif')" />
572- </div>
573- <div class="diffinfo" tal:condition="not:specific_path">
574- <div class="source_target" >
575+ <div class="diffBox">
576+ <a tal:attributes="href python:url(['/revision', change.revno, specific_path], clear=1);
577+ id string:${specific_path};
578+ title string:View changes to ${specific_path} only"
579+ class="the-link">
580+ <img tal:attributes="src python:branch.static_url('/static/images/treeExpanded.png');
581+ title python:branch.static_url('/static/images/treeCollapsed.png');
582+ alt python:branch.static_url('/static/images/treeExpanded.png')"
583+ class="expand_diff"/>
584+ <tal:b content="specific_path" />
585+ </a>
586+ </div>
587+ <div style="overflow: hidden">
588+ <div class="container">
589+ <div class="loading" style="display:none">
590+ <img tal:attributes="src python:branch.static_url('/static/images/spinner.gif')" />
591 </div>
592- </div>
593- <div class="diffinfo" tal:condition="specific_path">
594- <div class="pseudotable unified"
595- tal:repeat="chunk item/chunks">
596-
597- <tal:block condition="not:repeat/chunk/start">
598- <div class="pseudorow context-row">
599- <div class="lineNumber separate"></div>
600- <div class="lineNumber second separate"></div>
601- <div class="code separate"></div>
602+ <div class="diffinfo">
603+ <div class="pseudotable unified"
604+ tal:repeat="chunk diff_chunks">
605+
606+ <tal:block condition="not:repeat/chunk/start">
607+ <div class="pseudorow context-row">
608+ <div class="lineNumber separate"></div>
609+ <div class="lineNumber second separate"></div>
610+ <div class="code separate"></div>
611+ <div class="clear"><!-- --></div>
612+ </div>
613+ </tal:block>
614+
615+ <div tal:repeat="line chunk/diff"
616+ tal:attributes="class string:pseudorow ${line/type}-row">
617+ <div class="lineNumber first"
618+ tal:content="structure python:util.fill_div(line.old_lineno)"></div>
619+ <div class="lineNumber second"
620+ tal:content="structure python:util.fill_div(line.new_lineno)"></div>
621+ <div tal:attributes="class string:code ${line/type}"
622+ tal:content="structure python:util.fill_div(util.html_clean(line.line))"></div>
623 <div class="clear"><!-- --></div>
624 </div>
625- </tal:block>
626-
627- <div tal:repeat="line chunk/diff"
628- tal:attributes="class string:pseudorow ${line/type}-row">
629- <div class="lineNumber first"
630- tal:content="structure python:util.fill_div(line.old_lineno)"></div>
631- <div class="lineNumber second"
632- tal:content="structure python:util.fill_div(line.new_lineno)"></div>
633- <div tal:attributes="class string:code ${line/type}"
634- tal:content="structure python:util.fill_div(util.html_clean(line.line))"></div>
635- <div class="clear"><!-- --></div>
636- </div>
637- </div>
638- </div>
639- </div>
640- </div>
641- </div>
642+ </div>
643+ </div>
644+ </div>
645+ </div>
646+ </div>
647+ </tal:block>
648+
649+ <tal:block condition="not:specific_path">
650+ <div class="diff"
651+ tal:repeat="item file_changes/text_changes" tal:attributes="id string:diff-${item/index}">
652+
653+ <div class="diffBox">
654+ <a tal:attributes="href python:url(['/revision', change.revno, item.filename], clear=1);
655+ id string:${item/filename};
656+ title string:View changes to ${item/filename} only"
657+ class="the-link">
658+ <img tal:attributes="src python:branch.static_url('/static/images/treeCollapsed.png');
659+ title python:branch.static_url('/static/images/treeCollapsed.png');
660+ alt python:branch.static_url('/static/images/treeExpanded.png')"
661+ class="expand_diff" />
662+ <tal:b content="item/filename" />
663+ </a>
664+ </div>
665+ <div style="overflow: hidden">
666+ <div class="container">
667+ <div class="loading" style="display:none">
668+ <img tal:attributes="src python:branch.static_url('/static/images/spinner.gif')" />
669+ </div>
670+ <div class="diffinfo">
671+ <div class="source_target" >
672+ </div>
673+ </div>
674+ </div>
675+ </div>
676+ </div>
677+ </tal:block>
678
679 <ul tal:condition="python:navigation.prev_page_revid or navigation.next_page_revid"
680 id="pages">
681
682=== modified file 'loggerhead/templates/revisionfilechanges.pt'
683--- loggerhead/templates/revisionfilechanges.pt 2009-03-05 23:41:51 +0000
684+++ loggerhead/templates/revisionfilechanges.pt 2009-03-19 00:05:41 +0000
685@@ -1,5 +1,5 @@
686 <tal:block>
687- <ul tal:repeat="added entry/changes/added">
688+ <ul tal:repeat="added file_changes/added">
689 <tal:block condition="repeat/added/start">
690 <li class="desc">files added:</li>
691 </tal:block>
692@@ -11,7 +11,7 @@
693 </li>
694 </ul>
695
696- <ul tal:repeat="removed entry/changes/removed">
697+ <ul tal:repeat="removed file_changes/removed">
698 <tal:block condition="repeat/removed/start">
699 <li class="desc">files removed:</li>
700 </tal:block>
701@@ -23,7 +23,7 @@
702 </li>
703 </ul>
704
705- <ul tal:repeat="renamed entry/changes/renamed">
706+ <ul tal:repeat="renamed file_changes/renamed">
707 <tal:block condition="repeat/renamed/start">
708 <li class="desc">files renamed:</li>
709 </tal:block>
710@@ -39,7 +39,7 @@
711 </li>
712 </ul>
713
714- <ul tal:repeat="item entry/changes/modified">
715+ <ul tal:repeat="item file_changes/modified">
716 <tal:block condition="repeat/item/start">
717 <li class="desc">files modified:</li>
718 </tal:block>
719
720=== modified file 'loggerhead/templates/revisioninfo.pt'
721--- loggerhead/templates/revisioninfo.pt 2009-03-18 04:52:57 +0000
722+++ loggerhead/templates/revisioninfo.pt 2009-03-19 00:18:46 +0000
723@@ -15,8 +15,8 @@
724 <div class="revid" tal:content="string:Revision ID: ${change/revid}"></div>
725 <div class="information" tal:content="structure python:util.fixed_width(change.comment)"></div>
726 </div>
727- <ul id="list-files" tal:condition="include_file_list">
728- <tal:block content="structure python:file_change_summary(url, change, 'fragment', currently_showing)" />
729+ <ul id="list-files" tal:condition="file_changes">
730+ <tal:block content="structure python:file_change_summary(url, change, file_changes, 'fragment', currently_showing)" />
731 </ul>
732 <div class="clear"><!-- --></div>
733 </div>
734
735=== modified file 'loggerhead/templates/revlog.pt'
736--- loggerhead/templates/revlog.pt 2009-03-16 23:30:18 +0000
737+++ loggerhead/templates/revlog.pt 2009-03-19 00:27:08 +0000
738@@ -16,6 +16,6 @@
739 title="Show history" class="link"></a>
740 </li>
741 <li class="committerli" tal:content="python:', '.join(util.hide_emails(entry.authors))"></li>
742- <tal:block content="structure python:file_change_summary(url, entry)" />
743+ <tal:block content="structure python:file_change_summary(url, entry, file_changes)" />
744 </ul>
745 </div>

Subscribers

People subscribed via source and target branches