17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
from StringIO import StringIO
23
from bzrlib import errors
23
import json as simplejson
25
26
from paste.httpexceptions import HTTPServerError
27
28
from loggerhead import util
28
29
from loggerhead.controllers import TemplatedBranchView
29
from loggerhead.history import rich_filename
30
from loggerhead.controllers.filediff_ui import diff_chunks_for_file
32
33
DEFAULT_LINE_COUNT_LIMIT = 3000
36
return urllib.quote(urllib.quote(p, safe=''))
35
39
class RevisionUI(TemplatedBranchView):
37
41
template_path = 'loggerhead.templates.revision'
39
def _process_diff(self, diff):
40
# doesn't really need to be a method; could be static.
43
for line in diff.splitlines():
46
if line.startswith('+++ ') or line.startswith('--- '):
48
if line.startswith('@@ '):
52
chunk = util.Container()
54
split_lines = line.split(' ')[1:3]
55
lines = [int(x.split(',')[0][1:]) for x in split_lines]
58
elif line.startswith(' '):
59
chunk.diff.append(util.Container(old_lineno=old_lineno,
60
new_lineno=new_lineno,
65
elif line.startswith('+'):
66
chunk.diff.append(util.Container(old_lineno=None,
67
new_lineno=new_lineno,
68
type='insert', line=line[1:]))
70
elif line.startswith('-'):
71
chunk.diff.append(util.Container(old_lineno=old_lineno,
73
type='delete', line=line[1:]))
76
chunk.diff.append(util.Container(old_lineno=None,
84
def _parse_diffs(self, old_tree, new_tree, delta, specific_path):
86
Return a list of processed diffs, in the format::
95
type: str('context', 'delete', or 'insert'),
104
def include_specific_path(path):
105
return specific_path == path
106
def include_all_paths(path):
109
include_path = include_specific_path
111
include_path = include_all_paths
113
for old_path, new_path, fid, \
114
kind, text_modified, meta_modified in delta.renamed:
115
if text_modified and include_path(new_path):
116
process.append((old_path, new_path, fid, kind))
117
for path, fid, kind, text_modified, meta_modified in delta.modified:
118
if include_path(path):
119
process.append((path, path, fid, kind))
120
for path, fid, kind in delta.added:
121
if file == 'kind' and include_path(path):
122
process.append((path, path, fid, kind))
123
for path, fid, kind in delta.removed:
124
if file == 'kind' and include_path(path):
125
process.append((path, path, fid, kind))
127
process.sort(key=lambda x:x[1])
129
for old_path, new_path, fid, kind in process:
131
old_lines = old_tree.get_file_lines(fid)
132
except errors.NoSuchId:
135
new_lines = new_tree.get_file_lines(fid)
136
except errors.NoSuchId:
139
if old_lines != new_lines:
141
bzrlib.diff.internal_diff(old_path, old_lines,
142
new_path, new_lines, buffer)
143
except bzrlib.errors.BinaryFile:
146
diff = buffer.getvalue()
149
out.append(util.Container(
150
filename=rich_filename(new_path, kind), file_id=fid,
151
chunks=self._process_diff(diff)))
155
def get_changes_with_diff(self, change, compare_revid, specific_path):
157
if compare_revid is None:
159
compare_revid = change.parents[0].revid
161
compare_revid = 'null:'
163
rev_tree1 = h._branch.repository.revision_tree(compare_revid)
164
rev_tree2 = h._branch.repository.revision_tree(change.revid)
165
delta = rev_tree2.changes_from(rev_tree1)
167
changes = h.parse_delta(delta)
169
return changes, self._parse_diffs(
170
rev_tree1, rev_tree2, delta, specific_path)
172
43
def get_values(self, path, kwargs, headers):
174
45
revid = self.get_revid()
197
68
util.fill_in_navigation(navigation)
199
70
change = h.get_changes([revid])[0]
72
if compare_revid is None:
73
file_changes = h.get_file_changes(change)
75
file_changes = h.file_changes_for_revision_ids(
76
compare_revid, change.revid)
200
78
if path in ('', '/'):
202
change.changes, diffs = self.get_changes_with_diff(change, compare_revid, path)
203
# add parent & merge-point branch-nick info, in case it's useful
204
h.get_branch_nicks([change])
84
item = [x for x in file_changes.text_changes if x.filename == path][0]
85
diff_chunks = diff_chunks_for_file(
86
self._history._branch.repository, item.file_id,
87
item.old_revision, item.new_revision)
90
for i, item in enumerate(file_changes.text_changes):
92
link_data['diff-' + str(i)] = '%s/%s/%s' % (
93
dq(item.new_revision), dq(item.old_revision), dq(item.file_id))
94
path_to_id[item.filename] = 'diff-' + str(i)
96
h.add_branch_nicks(change)
206
98
# Directory Breadcrumbs
207
99
directory_breadcrumbs = (