def _content_changes(old_node, new_node): """Returns the list of differences. The list is empty when no differences between comparable files are detected, but the return value is None for non-comparable files. """ mview = Mimeview(self.env) if mview.is_binary(old_node.content_type, old_node.path): return None if mview.is_binary(new_node.content_type, new_node.path): return None old_content = old_node.get_content().read() if mview.is_binary(content=old_content): return None new_content = new_node.get_content().read() if mview.is_binary(content=new_content): return None old_content = mview.to_unicode(old_content, old_node.content_type) new_content = mview.to_unicode(new_content, new_node.content_type) if old_content != new_content: context = options.get('contextlines', 3) if context < 0: context = None tabwidth = self.config['diff'].getint('tab_width') or \ self.config['mimeviewer'].getint('tab_width', 8) ignore_blank_lines = options.get('ignoreblanklines') ignore_case = options.get('ignorecase') ignore_space = options.get('ignorewhitespace') return diff_blocks(old_content.splitlines(), new_content.splitlines(), context, tabwidth, ignore_blank_lines=ignore_blank_lines, ignore_case=ignore_case, ignore_space_changes=ignore_space) else: return []
def _render_diff(self, req, filename, repos, data): """Raw Unified Diff version""" req.send_response(200) req.send_header('Content-Type', 'text/x-patch;charset=utf-8') req.send_header('Content-Disposition', content_disposition('inline', filename + '.diff')) buf = StringIO() mimeview = Mimeview(self.env) for old_node, new_node, kind, change in repos.get_changes( new_path=data['new_path'], new_rev=data['new_rev'], old_path=data['old_path'], old_rev=data['old_rev']): # TODO: Property changes # Content changes if kind == Node.DIRECTORY: continue new_content = old_content = '' new_node_info = old_node_info = ('','') mimeview = Mimeview(self.env) if old_node: if mimeview.is_binary(old_node.content_type, old_node.path): continue old_content = old_node.get_content().read() if mimeview.is_binary(content=old_content): continue old_node_info = (old_node.path, old_node.rev) old_content = mimeview.to_unicode(old_content, old_node.content_type) if new_node: if mimeview.is_binary(new_node.content_type, new_node.path): continue new_content = new_node.get_content().read() if mimeview.is_binary(content=new_content): continue new_node_info = (new_node.path, new_node.rev) new_path = new_node.path new_content = mimeview.to_unicode(new_content, new_node.content_type) else: old_node_path = repos.normalize_path(old_node.path) diff_old_path = repos.normalize_path(data['old_path']) new_path = posixpath.join(data['new_path'], old_node_path[len(diff_old_path)+1:]) if old_content != new_content: options = data['diff']['options'] context = options.get('contextlines', 3) if context < 0: context = 3 # FIXME: unified_diff bugs with context=None ignore_blank_lines = options.get('ignoreblanklines') ignore_case = options.get('ignorecase') ignore_space = options.get('ignorewhitespace') if not old_node_info[0]: old_node_info = new_node_info # support for 'A'dd changes buf.write('Index: ' + new_path + CRLF) buf.write('=' * 67 + CRLF) buf.write('--- %s\t(revision %s)' % old_node_info + CRLF) buf.write('+++ %s\t(revision %s)' % new_node_info + CRLF) for line in unified_diff(old_content.splitlines(), new_content.splitlines(), context, ignore_blank_lines=ignore_blank_lines, ignore_case=ignore_case, ignore_space_changes=ignore_space): buf.write(line + CRLF) diff_str = buf.getvalue().encode('utf-8') req.send_header('Content-Length', len(diff_str)) req.end_headers() req.write(diff_str) raise RequestDone