%def name="diff_line_anchor(filename, line, type)"><%
return '%s_%s_%i' % (h.safeid(filename), type, line)
%>%def>
<%def name="action_class(action)"><%
return {
'-': 'cb-deletion',
'+': 'cb-addition',
' ': 'cb-context',
}.get(action, 'cb-empty')
%>%def>
<%def name="op_class(op_id)"><%
return {
DEL_FILENODE: 'deletion', # file deleted
BIN_FILENODE: 'warning' # binary diff hidden
}.get(op_id, 'addition')
%>%def>
<%def name="link_for(**kw)"><%
new_args = request.GET.mixed()
new_args.update(kw)
return h.url('', **new_args)
%>%def>
<%def name="render_diffset(diffset,
# collapse all file diff entries when there are more than this amount of files in the diff
collapse_when_files_over=20,
# collapse lines in the diff when more than this amount of lines changed in the file diff
lines_changed_limit=500,
)">
<%
# TODO: dan: move this to an argument - and set a cookie so that it is saved
# default option for future requests
diff_mode = request.GET.get('diffmode', 'sideside')
if diff_mode not in ('sideside', 'unified'):
diff_mode = 'sideside'
collapse_all = len(diffset.files) > collapse_when_files_over
%>
%if diff_mode == 'sideside':
%endif
% if diffset.limited_diff:
% endif
%if diffset.files:
%endif
%if diffset.limited_diff:
${ungettext('%(num)s file changed', '%(num)s files changed', diffset.changed_files) % {'num': diffset.changed_files}}
%else:
${ungettext('%(num)s file changed: %(linesadd)s inserted, ''%(linesdel)s deleted',
'%(num)s files changed: %(linesadd)s inserted, %(linesdel)s deleted', diffset.changed_files) % {'num': diffset.changed_files, 'linesadd': diffset.lines_added, 'linesdel': diffset.lines_deleted}}
%endif
%if not diffset.files:
${_('No files')}
%endif
%for i, filediff in enumerate(diffset.files):
<%
lines_changed = filediff['patch']['stats']['added'] + filediff['patch']['stats']['deleted']
over_lines_changed_limit = lines_changed > lines_changed_limit
%>
${diff_ops(filediff)}
${diff_menu(filediff)}
%if not filediff.hunks:
%for op_id, op_text in filediff['patch']['stats']['ops'].items():
%if op_id == DEL_FILENODE:
${_('File was deleted')}
%elif op_id == BIN_FILENODE:
${_('Binary file hidden')}
%else:
${op_text}
%endif
%endfor
%endif
%if over_lines_changed_limit:
${_('This diff has been collapsed as it changes many lines, (%i lines changed)' % lines_changed)}
${_('Show them')}
${_('Hide them')}
%endif
%if filediff.patch['is_limited_diff']:
${_('The requested commit is too big and content was truncated.')} ${_('Show full diff')}
%endif
%for hunk in filediff.hunks:
## TODO: dan: add ajax loading of more context here
##
##
@@
-${hunk.source_start},${hunk.source_length}
+${hunk.target_start},${hunk.target_length}
${hunk.section_header}
%if diff_mode == 'unified':
${render_hunk_lines_unified(hunk)}
%elif diff_mode == 'sideside':
${render_hunk_lines_sideside(hunk)}
%else:
unknown diff mode
%endif
%endfor
%endfor
%def>
<%def name="diff_ops(filediff)">
<%
stats = filediff['patch']['stats']
from rhodecode.lib.diffs import NEW_FILENODE, DEL_FILENODE, \
MOD_FILENODE, RENAMED_FILENODE, CHMOD_FILENODE, BIN_FILENODE
%>
%if filediff.source_file_path and filediff.target_file_path:
%if filediff.source_file_path != filediff.target_file_path: # file was renamed
${filediff.target_file_path} ⬅ ${filediff.source_file_path}
%else:
## file was modified
${filediff.source_file_path}
%endif
%else:
%if filediff.source_file_path:
## file was deleted
${filediff.source_file_path}
%else:
## file was added
${filediff.target_file_path}
%endif
%endif
%if filediff.patch['is_limited_diff']:
limited diff
%endif
%if RENAMED_FILENODE in stats['ops']:
renamed
%endif
%if NEW_FILENODE in stats['ops']:
created
%if filediff['target_mode'].startswith('120'):
symlink
%else:
${nice_mode(filediff['target_mode'])}
%endif
%endif
%if DEL_FILENODE in stats['ops']:
removed
%endif
%if CHMOD_FILENODE in stats['ops']:
${nice_mode(filediff['source_mode'])} ➡ ${nice_mode(filediff['target_mode'])}
%endif
¶
%if BIN_FILENODE in stats['ops']:
binary
%if MOD_FILENODE in stats['ops']:
modified
%endif
%endif
%if stats['deleted']:
-${stats['deleted']}
%endif
%if stats['added']:
+${stats['added']}
%endif
%def>
<%def name="nice_mode(filemode)">
${filemode.startswith('100') and filemode[3:] or filemode}
%def>
<%def name="diff_menu(filediff)">
%def>
<%def name="render_hunk_lines_sideside(hunk)">
%for i, line in enumerate(hunk.sideside):
<%
old_line_anchor, new_line_anchor = None, None
if line.original.lineno:
old_line_anchor = diff_line_anchor(hunk.filediff.source_file_path, line.original.lineno, 'o')
if line.modified.lineno:
new_line_anchor = diff_line_anchor(hunk.filediff.target_file_path, line.modified.lineno, 'n')
%>
%if line.original.lineno:
${line.original.lineno}
%endif
${line.original.action} ${line.original.content or '' | n}
%if line.modified.lineno:
${line.modified.lineno}
%endif
${line.modified.action} ${line.modified.content or '' | n}
%endfor
%def>
<%def name="render_hunk_lines_unified(hunk)">
%for old_line_no, new_line_no, action, content in hunk.unified:
<%
old_line_anchor, new_line_anchor = None, None
if old_line_no:
old_line_anchor = diff_line_anchor(hunk.filediff.source_file_path, old_line_no, 'o')
if new_line_no:
new_line_anchor = diff_line_anchor(hunk.filediff.target_file_path, new_line_no, 'n')
%>
%if old_line_anchor:
${old_line_no}
%endif
%if new_line_anchor:
${new_line_no}
%endif
${action} ${content or '' | n}
%endfor
%def>