17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
from cherrypy import InternalError
20
from StringIO import StringIO
24
from paste.httpexceptions import HTTPServerError
25
26
from loggerhead import util
28
class RevisionUI (object):
30
def __init__(self, branch):
36
@util.strip_whitespace
37
@turbogears.expose(html='loggerhead.templates.revision')
38
def default(self, *args, **kw):
40
h = self._branch.get_history()
27
from loggerhead.controllers import TemplatedBranchView
28
from loggerhead.history import rich_filename
31
DEFAULT_LINE_COUNT_LIMIT = 3000
34
class RevisionUI(TemplatedBranchView):
36
template_path = 'loggerhead.templates.revision'
38
def _process_diff(self, diff):
39
# doesn't really need to be a method; could be static.
42
for line in diff.splitlines():
45
if line.startswith('+++ ') or line.startswith('--- '):
47
if line.startswith('@@ '):
51
chunk = util.Container()
53
split_lines = line.split(' ')[1:3]
54
lines = [int(x.split(',')[0][1:]) for x in split_lines]
57
elif line.startswith(' '):
58
chunk.diff.append(util.Container(old_lineno=old_lineno,
59
new_lineno=new_lineno,
64
elif line.startswith('+'):
65
chunk.diff.append(util.Container(old_lineno=None,
66
new_lineno=new_lineno,
67
type='insert', line=line[1:]))
69
elif line.startswith('-'):
70
chunk.diff.append(util.Container(old_lineno=old_lineno,
72
type='delete', line=line[1:]))
75
chunk.diff.append(util.Container(old_lineno=None,
83
def _parse_diffs(self, old_tree, new_tree, delta):
85
Return a list of processed diffs, in the format::
94
type: str('context', 'delete', or 'insert'),
103
for old_path, new_path, fid, \
104
kind, text_modified, meta_modified in delta.renamed:
106
process.append((old_path, new_path, fid, kind))
107
for path, fid, kind, text_modified, meta_modified in delta.modified:
108
process.append((path, path, fid, kind))
110
for old_path, new_path, fid, kind in process:
111
old_lines = old_tree.get_file_lines(fid)
112
new_lines = new_tree.get_file_lines(fid)
114
if old_lines != new_lines:
116
bzrlib.diff.internal_diff(old_path, old_lines,
117
new_path, new_lines, buffer)
118
except bzrlib.errors.BinaryFile:
121
diff = buffer.getvalue()
124
out.append(util.Container(
125
filename=rich_filename(new_path, kind),
127
chunks=self._process_diff(diff),
132
def get_change_with_diff(self, revid, compare_revid):
134
change = h.get_changes([revid])[0]
136
if compare_revid is None:
138
compare_revid = change.parents[0].revid
140
compare_revid = 'null:'
142
rev_tree1 = h._branch.repository.revision_tree(compare_revid)
143
rev_tree2 = h._branch.repository.revision_tree(revid)
144
delta = rev_tree2.changes_from(rev_tree1)
146
change.changes = h.parse_delta(delta)
147
change.changes.modified = self._parse_diffs(rev_tree1,
153
def get_values(self, path, kwargs, headers):
155
revid = self.get_revid()
157
filter_file_id = kwargs.get('filter_file_id', None)
158
start_revid = h.fix_revid(kwargs.get('start_revid', None))
159
query = kwargs.get('q', None)
160
remember = h.fix_revid(kwargs.get('remember', None))
161
compare_revid = h.fix_revid(kwargs.get('compare_revid', None))
46
revid = h.fix_revid(args[0])
50
filter_file_id = kw.get('filter_file_id', None)
51
start_revid = h.fix_revid(kw.get('start_revid', None))
52
query = kw.get('q', None)
53
remember = kw.get('remember', None)
54
compare_revid = kw.get('compare_revid', None)
57
revid, start_revid, revid_list = h.get_view(revid, start_revid, filter_file_id, query)
59
self.log.exception('Exception fetching changes')
60
raise InternalError('Could not fetch changes')
62
navigation = util.Container(
63
revid_list=revid_list, revid=revid, start_revid=start_revid,
64
filter_file_id=filter_file_id, pagesize=1,
65
scan_url='/revision', branch=self._branch, feed=True)
67
navigation.query = query
68
util.fill_in_navigation(navigation)
70
change = h.get_change_with_diff(revid, compare_revid)
71
# add parent & merge-point branch-nick info, in case it's useful
72
h.get_branch_nicks([ change ])
74
# let's make side-by-side diff be the default
75
side_by_side = not kw.get('unified', False)
77
h.add_side_by_side([ change ])
80
'branch': self._branch,
83
'start_revid': start_revid,
84
'filter_file_id': filter_file_id,
87
'navigation': navigation,
90
'compare_revid': compare_revid,
91
'side_by_side': side_by_side,
94
self.log.info('/revision: %r seconds' % (time.time() - z,))
164
revid, start_revid, revid_list = h.get_view(revid,
169
self.log.exception('Exception fetching changes')
170
raise HTTPServerError('Could not fetch changes')
172
navigation = util.Container(
173
revid_list=revid_list, revid=revid, start_revid=start_revid,
174
filter_file_id=filter_file_id, pagesize=1,
175
scan_url='/revision', branch=self._branch, feed=True, history=h)
176
if query is not None:
177
navigation.query = query
178
util.fill_in_navigation(navigation)
180
change = self.get_change_with_diff(revid, compare_revid)
181
# add parent & merge-point branch-nick info, in case it's useful
182
h.get_branch_nicks([change])
184
line_count_limit = DEFAULT_LINE_COUNT_LIMIT
186
for file in change.changes.modified:
187
for chunk in file.chunks:
188
line_count += len(chunk.diff)
190
# Directory Breadcrumbs
191
directory_breadcrumbs = (
192
util.directory_breadcrumbs(
193
self._branch.friendly_name,
194
self._branch.is_root,
198
'branch': self._branch,
201
'start_revid': start_revid,
202
'filter_file_id': filter_file_id,
205
'navigation': navigation,
207
'remember': remember,
208
'compare_revid': compare_revid,
209
'url': self._branch.context_url,
210
'line_count': line_count,
211
'line_count_limit': line_count_limit,
212
'show_plain_diffs': line_count > line_count_limit,
213
'directory_breadcrumbs': directory_breadcrumbs,