Mercurial > kallithea
comparison rhodecode/controllers/changeset.py @ 1789:17caf4efe15c beta
implements #308 rewrote diffs to enable displaying full diff on each file
- fixed escaping of html special chars in file editor
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 19 Dec 2011 00:11:20 +0200 |
parents | d4a7b6c82efe |
children | 89efedac4e6c |
comparison
equal
deleted
inserted
replaced
1788:ef0613584ced | 1789:17caf4efe15c |
---|---|
44 from rhodecode.lib.compat import OrderedDict | 44 from rhodecode.lib.compat import OrderedDict |
45 from rhodecode.lib import diffs | 45 from rhodecode.lib import diffs |
46 from rhodecode.model.db import ChangesetComment | 46 from rhodecode.model.db import ChangesetComment |
47 from rhodecode.model.comment import ChangesetCommentsModel | 47 from rhodecode.model.comment import ChangesetCommentsModel |
48 from rhodecode.model.meta import Session | 48 from rhodecode.model.meta import Session |
49 from rhodecode.lib.diffs import wrapped_diff | |
49 | 50 |
50 log = logging.getLogger(__name__) | 51 log = logging.getLogger(__name__) |
51 | 52 |
52 | 53 |
53 def anchor_url(revision, path): | 54 def anchor_url(revision, path): |
143 | 144 |
144 params['anchor'] = fileid | 145 params['anchor'] = fileid |
145 return h.link_to(lbl, h.url.current(**params)) | 146 return h.link_to(lbl, h.url.current(**params)) |
146 | 147 |
147 | 148 |
148 def wrap_to_table(str_): | |
149 return '''<table class="code-difftable"> | |
150 <tr class="line no-comment"> | |
151 <td class="lineno new"></td> | |
152 <td class="code no-comment"><pre>%s</pre></td> | |
153 </tr> | |
154 </table>''' % str_ | |
155 | |
156 | |
157 class ChangesetController(BaseRepoController): | 149 class ChangesetController(BaseRepoController): |
158 | 150 |
159 @LoginRequired() | 151 @LoginRequired() |
160 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | 152 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
161 'repository.admin') | 153 'repository.admin') |
190 log.error(traceback.format_exc()) | 182 log.error(traceback.format_exc()) |
191 h.flash(str(e), category='warning') | 183 h.flash(str(e), category='warning') |
192 return redirect(url('home')) | 184 return redirect(url('home')) |
193 | 185 |
194 c.changes = OrderedDict() | 186 c.changes = OrderedDict() |
195 c.sum_added = 0 | 187 |
196 c.sum_removed = 0 | 188 c.lines_added = 0 # count of lines added |
197 c.lines_added = 0 | 189 c.lines_deleted = 0 # count of lines removes |
198 c.lines_deleted = 0 | 190 |
191 cumulative_diff = 0 | |
199 c.cut_off = False # defines if cut off limit is reached | 192 c.cut_off = False # defines if cut off limit is reached |
200 | 193 |
201 c.comments = [] | 194 c.comments = [] |
202 c.inline_comments = [] | 195 c.inline_comments = [] |
203 c.inline_cnt = 0 | 196 c.inline_cnt = 0 |
218 | 211 |
219 #================================================================== | 212 #================================================================== |
220 # ADDED FILES | 213 # ADDED FILES |
221 #================================================================== | 214 #================================================================== |
222 for node in changeset.added: | 215 for node in changeset.added: |
223 | 216 fid = h.FID(revision, node.path) |
224 filenode_old = FileNode(node.path, '', EmptyChangeset()) | 217 line_context_lcl = get_line_ctx(fid, request.GET) |
225 if filenode_old.is_binary or node.is_binary: | 218 ign_whitespace_lcl = get_ignore_ws(fid, request.GET) |
226 diff = wrap_to_table(_('binary file')) | 219 lim = self.cut_off_limit |
227 st = (0, 0) | 220 if cumulative_diff > self.cut_off_limit: |
228 else: | 221 lim = -1 |
229 # in this case node.size is good parameter since those are | 222 size, cs1, cs2, diff, st = wrapped_diff(filenode_old=None, |
230 # added nodes and their size defines how many changes were | 223 filenode_new=node, |
231 # made | 224 cut_off_limit=lim, |
232 c.sum_added += node.size | 225 ignore_whitespace=ign_whitespace_lcl, |
233 fid = h.FID(revision, node.path) | 226 line_context=line_context_lcl, |
234 line_context_lcl = get_line_ctx(fid, request.GET) | 227 enable_comments=enable_comments) |
235 ignore_whitespace_lcl = get_ignore_ws(fid, request.GET) | 228 cumulative_diff += size |
236 if c.sum_added < self.cut_off_limit: | |
237 f_gitdiff = diffs.get_gitdiff(filenode_old, node, | |
238 ignore_whitespace=ignore_whitespace_lcl, | |
239 context=line_context_lcl) | |
240 d = diffs.DiffProcessor(f_gitdiff, format='gitdiff') | |
241 | |
242 st = d.stat() | |
243 diff = d.as_html(enable_comments=enable_comments) | |
244 | |
245 else: | |
246 diff = wrap_to_table(_('Changeset is to big and ' | |
247 'was cut off, see raw ' | |
248 'changeset instead')) | |
249 c.cut_off = True | |
250 break | |
251 | |
252 cs1 = None | |
253 cs2 = node.last_changeset.raw_id | |
254 c.lines_added += st[0] | 229 c.lines_added += st[0] |
255 c.lines_deleted += st[1] | 230 c.lines_deleted += st[1] |
256 c.changes[changeset.raw_id].append(('added', node, diff, | 231 c.changes[changeset.raw_id].append(('added', node, diff, |
257 cs1, cs2, st)) | 232 cs1, cs2, st)) |
258 | 233 |
259 #================================================================== | 234 #================================================================== |
260 # CHANGED FILES | 235 # CHANGED FILES |
261 #================================================================== | 236 #================================================================== |
262 if not c.cut_off: | 237 for node in changeset.changed: |
263 for node in changeset.changed: | 238 try: |
264 try: | 239 filenode_old = changeset_parent.get_node(node.path) |
265 filenode_old = changeset_parent.get_node(node.path) | 240 except ChangesetError: |
266 except ChangesetError: | 241 log.warning('Unable to fetch parent node for diff') |
267 log.warning('Unable to fetch parent node for diff') | 242 filenode_old = FileNode(node.path, '', EmptyChangeset()) |
268 filenode_old = FileNode(node.path, '', | 243 |
269 EmptyChangeset()) | 244 fid = h.FID(revision, node.path) |
270 | 245 line_context_lcl = get_line_ctx(fid, request.GET) |
271 if filenode_old.is_binary or node.is_binary: | 246 ign_whitespace_lcl = get_ignore_ws(fid, request.GET) |
272 diff = wrap_to_table(_('binary file')) | 247 lim = self.cut_off_limit |
273 st = (0, 0) | 248 if cumulative_diff > self.cut_off_limit: |
274 else: | 249 lim = -1 |
275 | 250 size, cs1, cs2, diff, st = wrapped_diff(filenode_old=filenode_old, |
276 if c.sum_removed < self.cut_off_limit: | 251 filenode_new=node, |
277 fid = h.FID(revision, node.path) | 252 cut_off_limit=lim, |
278 line_context_lcl = get_line_ctx(fid, request.GET) | 253 ignore_whitespace=ign_whitespace_lcl, |
279 ignore_whitespace_lcl = get_ignore_ws(fid, request.GET,) | 254 line_context=line_context_lcl, |
280 f_gitdiff = diffs.get_gitdiff(filenode_old, node, | 255 enable_comments=enable_comments) |
281 ignore_whitespace=ignore_whitespace_lcl, | 256 cumulative_diff += size |
282 context=line_context_lcl) | 257 c.lines_added += st[0] |
283 d = diffs.DiffProcessor(f_gitdiff, | 258 c.lines_deleted += st[1] |
284 format='gitdiff') | 259 c.changes[changeset.raw_id].append(('changed', node, diff, |
285 st = d.stat() | 260 cs1, cs2, st)) |
286 if (st[0] + st[1]) * 256 > self.cut_off_limit: | |
287 diff = wrap_to_table(_('Diff is to big ' | |
288 'and was cut off, see ' | |
289 'raw diff instead')) | |
290 else: | |
291 diff = d.as_html(enable_comments=enable_comments) | |
292 | |
293 if diff: | |
294 c.sum_removed += len(diff) | |
295 else: | |
296 diff = wrap_to_table(_('Changeset is to big and ' | |
297 'was cut off, see raw ' | |
298 'changeset instead')) | |
299 c.cut_off = True | |
300 break | |
301 | |
302 cs1 = filenode_old.last_changeset.raw_id | |
303 cs2 = node.last_changeset.raw_id | |
304 c.lines_added += st[0] | |
305 c.lines_deleted += st[1] | |
306 c.changes[changeset.raw_id].append(('changed', node, diff, | |
307 cs1, cs2, st)) | |
308 | 261 |
309 #================================================================== | 262 #================================================================== |
310 # REMOVED FILES | 263 # REMOVED FILES |
311 #================================================================== | 264 #================================================================== |
312 if not c.cut_off: | 265 for node in changeset.removed: |
313 for node in changeset.removed: | 266 c.changes[changeset.raw_id].append(('removed', node, None, |
314 c.changes[changeset.raw_id].append(('removed', node, None, | 267 None, None, (0, 0))) |
315 None, None, (0, 0))) | |
316 | 268 |
317 # count inline comments | 269 # count inline comments |
318 for path, lines in c.inline_comments: | 270 for path, lines in c.inline_comments: |
319 for comments in lines.values(): | 271 for comments in lines.values(): |
320 c.inline_cnt += len(comments) | 272 c.inline_cnt += len(comments) |