Merge lp:~mwhudson/loggerhead/iter_changes-forevar into lp:loggerhead
- iter_changes-forevar
- Merge into trunk-rich
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 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Albisetti | Approve | ||
Review via email: mp+4644@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote : | # |
- 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> |
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.