home » zplus/clif.git
ID: 56667cefa2ec78a94750f691e90bf78f90499aaf
376 lines — 19K — View raw


{% extends "repository/repository.html" %}

{% block page_title %}Commit: {{ commit.id }}{% endblock %}

{% block content %}
    
    <div class="commit">
        <table>
            <tbody>
                <tr>
                    <td>
                        <b>Author</b>
                    </td>
                    <td>
                        {{ commit.author }}
                        {{ commit_time(commit.author.time, commit.author.offset) }}
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Committer</b>
                    </td>
                    <td>
                        {{ commit.committer }}
                        {{ commit_time(commit.committer.time, commit.committer.offset) }}
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Commit</b>
                    </td>
                    <td>
                        <a href="{{ url('commit', repository=repository[:-4], commit_id=commit.id) }}">{{ commit.id }}</a>
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Tree</b>
                    </td>
                    <td>
                        <a href="{{ url('tree', repository=repository[:-4], revision=commit.tree.id) }}">{{ commit.tree.id }}</a>
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Parent(s)</b>
                    </td>
                    <td>
                        {% for parent in commit.parents %}
                            <a href="{{ url('commit', repository=repository[:-4], commit_id=parent.id) }}">{{ parent.short_id }}</a>
                        {% endfor %}
                    </td>
                </tr>
            </tbody>
        </table>
        
        <br />
        
        <div class="message">{{ commit.message }}</div>
        
        <br /><br /><br /><br />
        
        <details class="diffstat" {{ 'open' if defaults.DIFF_EXPAND_DIFFSTAT }}>
            {# pygit2 appears to recompute all the stats every time we use diff.stats,
             # therefore we set this variable in order to compute it only once.
             #}
            {% set diff_stats = diff.stats %}
        
            <summary>Diffstat</summary>
            <table>
                {% for patch in diff %}
                    <tr>
                        <td class="filemode">{{ patch.delta.new_file.mode|filemode }}</td>
                        <td class="path">
                            <a href="#{{ (patch.delta.new_file.id|string)[:7] }}">{{ patch.delta.new_file.path }}</a>
                        </td>
                        <td class="lines">{{ patch.line_stats[1] + patch.line_stats[2] }}</td>
                        <td class="histogram">
                            {% if diff_stats.insertions + diff_stats.deletions > 0 %}
                                <span title="+{{ patch.line_stats[1] }}" class="insertions" style="width:{{ patch.line_stats[1] / (diff_stats.insertions + diff_stats.deletions) * 100 }}%"></span
                                ><span title="-{{ patch.line_stats[2] }}" class="deletions" style="width:{{ patch.line_stats[2] / (diff_stats.insertions + diff_stats.deletions) * 100 }}%"></span>
                            {% endif %}
                        </td>
                        <td></td>
                    </tr>
                {% endfor %}
            </table>
            
            <div class="accumulated">
                <b>{{ diff_stats.files_changed }}</b> file{{ 's' if diff_stats.files_changed != 1 }} changed,
                <span class="insertions"><b>{{ diff_stats.insertions }}</b> insertion{{ 's' if diff_stats.insertions != 1 }}</span>,
                <span class="deletions"><b>{{ diff_stats.deletions }}</b> deletion{{ 's' if diff_stats.deletions != 1 }}</span>
            </div>
        </details>
        
        <br />
        
        <details class="diff_options" {{ 'open' if defaults.DIFF_EXPAND_DIFFOPTIONS }}>
            <summary>Diff options</summary>
            <form action="" method="get">
                <table>
                    <tr>
                        <td>
                            View
                        </td>
                        <td>
                            <label><input type="radio" name="mode" value="udiff" {{ 'checked' if mode == 'udiff' }}>Unified</label>
                            <label><input type="radio" name="mode" value="udiff_raw" {{ 'checked' if mode == 'udiff_raw' }}>Unified (raw)</label>
                            <label><input type="radio" name="mode" value="ssdiff" {{ 'checked' if mode == 'ssdiff' }}>Side by side</label>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Context lines
                        </td>
                        <td>
                            <input type="number" min=0 max=1000 name="context_lines" value="{{ context_lines }}" />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Inter-hunk lines
                        </td>
                        <td>
                            <input type="number" min=0 max=1000 name="inter_hunk_lines" value="{{ inter_hunk_lines }}" />
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Side
                        </td>
                        <td>
                            <label><input type="radio" name="side" value="normal" {{ 'checked' if side == 'normal' }}>Normal</label>
                            <label><input type="radio" name="side" value="reverse" {{ 'checked' if side == 'reverse' }}>Reverse</label>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            Whitespace
                        </td>
                        <td>
                            <label><input type="radio" name="whitespace" value="include" {{ 'checked' if whitespace == 'include' }}>Include</label>
                            <label><input type="radio" name="whitespace" value="ignore_all" {{ 'checked' if whitespace == 'ignore_all' }}>Ignore all</label>
                            <label><input type="radio" name="whitespace" value="ignore_change" {{ 'checked' if whitespace == 'ignore_change' }}>Ignore amount changes</label>
                            <label><input type="radio" name="whitespace" value="ignore_eol" {{ 'checked' if whitespace == 'ignore_eol' }}>Ignore at end of line</label>
                        </td>
                    </tr>
                </table>
                <input type="submit" value="Update" />
            </form>
        </details>
        
        {% if mode == 'udiff_raw' %}
        
            <div class="raw_diff">{{ diff.patch|highlight_udiff|safe }}</div>
            
        {% else %}
        
        {% for patch in diff %}
            
            {# The following status values are defined in the git_delta_t enum
             # in libgit2. See https://github.com/libgit2/libgit2/blob/main/include/git2/diff.h
             # Looks like pygit2 also has a pygit2.DiffDelta.status_char() functions that
             # returns the single-char abbreviation of the delta status, so we can use this
             # instead of the raw integer.
             # 0 = UNCHANGED
             # 1 = ADDED (does not exist in old version)
             # 2 = DELETED (does not exist in new version)
             # 3 = MODIFIED (content changed between old and new versions)
             # 4 = RENAMED
             # 5 = COPIED
             # ... (there are other codes that we don't use)
             #}
            
            {% set delta_char = patch.delta.status_char() %}
            
            <details class="diff_view" id="{{ (patch.delta.new_file.id|string)[:7] }}" {{ 'open' if defaults.DIFF_EXPAND }}>
            
                <summary>
                    {% if patch.line_stats[1] + patch.line_stats[2] > 0 %}
                        {% set color_border = patch.line_stats[1] / ( patch.line_stats[1] + patch.line_stats[2] ) * 100 %}
                    {% else %}
                        {% set color_border = 0 %}
                    {% endif %}
                    
                    <span class="histogram" style="border-image: linear-gradient(to right, lightgreen {{ color_border }}%, red {{ color_border }}%) 1;">
                        +{{ patch.line_stats[1] }}/-{{ patch.line_stats[2] }}
                    </span>
                    
                    {% if delta_char == 'A' %}
                        <b title="Added">A</b> &nbsp; {{ patch.delta.new_file.path }}
                    {% endif %}
                    
                    {% if delta_char == 'D' %}
                        <b title="Deleted">D</b> &nbsp; {{ patch.delta.old_file.path }}
                    {% endif %}
                    
                    {% if delta_char == 'M' %}
                        <b title="Modified">M</b> &nbsp; {{ patch.delta.new_file.path }}
                    {% endif %}
                    
                    {% if delta_char == 'R' %}
                        <b title="Renamed">R</b> &nbsp; {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
                    {% endif %}
                    
                    {% if delta_char == 'C' %}
                        <b title="Copied">C</b> &nbsp; {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
                    {% endif %}
            
                    <table>
                        <tr>
                            <td>
                                index <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}">{{ (patch.delta.old_file.id|string)[:7] }}</a>..<a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}">{{ (patch.delta.new_file.id|string)[:7] }}</a>
                            </td>
                        </tr>
                        <tr>
                            <td colspan="4">
                                old size: {{ patch.delta.old_file.size|human_size(B=true) }}
                                - 
                                new size: {{ patch.delta.new_file.size|human_size(B=true) }}
                            </td>
                        </tr>
                        <tr>
                            <td colspan="4">
                                {% if delta_char == 'A' %}
                                    new file mode: {{ patch.delta.new_file.mode|filemode }}
                                {% elif delta_char == 'D' %}
                                    deleted file mode: {{ patch.delta.old_file.mode|filemode }}
                                {% elif patch.delta.old_file.mode != patch.delta.new_file.mode %}
                                    old mode: {{ patch.delta.old_file.mode|filemode }}
                                    <br />
                                    new mode: {{ patch.delta.new_file.mode|filemode }}
                                {% endif %}
                            </td>
                        </tr>
                    </table>
                </summary>
        
                <table class="diff">
                    {% if patch.delta.is_binary %}
                        <tr>
                            <td colspan="4">
                                <i>Binary file</i>
                            </td>
                        </tr>
                    {% endif %}
                    
                    {% for hunk in patch.hunks if not patch.delta.is_binary %}
                        
                        {#### UDIFF mode ####}
                        {# In this mode the lines are printed one after the other. #}
                        
                        {% if mode == 'udiff' %}
                            <tr class="header">
                                <td></td>
                                <td></td>
                                <td></td>
                                <td>{{ hunk.header }}</td>
                            </tr>
                            
                            {% for line in hunk.lines %}
                                <tr class="udiff {{ 'insertion' if line.old_lineno < 0 }} {{ 'deletion' if line.new_lineno < 0 }}">
                                    <td class="linenos">
                                        {% if line.old_lineno >= 0 %}
                                            <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}#line-{{ line.old_lineno }}">{{ line.old_lineno }}</a>
                                        {% endif %}
                                    </td>
                                    <td class="linenos">
                                        {% if line.new_lineno >= 0 %}
                                            <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ line.new_lineno }}">{{ line.new_lineno }}</a>
                                        {% endif %}
                                    </td>
                                    <td class="origin">{{ line.origin }}</td>
                                    <td class="content">{{ line.content }}</td>
                                </tr>
                            {% endfor %}
                        {% endif %}
                        
                        {#### SSDIFF mode ####}
                        {# In this mode, changed lines are buffered until we find an
                         # unchanged line. When an unchanged line has been found, the
                         # buffer is emptied.
                         #}
                        
                        {% if mode == 'ssdiff' %}
                            {% set buffer_deletions = [] %}
                            {% set buffer_insertions = [] %}
                            
                            {% macro print_buffer(buffer_deletions, buffer_insertions) %}
                                {% for buffer_del, buffer_ins in zip_longest(buffer_deletions, buffer_insertions) %}
                                    <tr class="ssdiff">
                                        {% if buffer_del %}
                                            <td class="linenos">
                                                <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}#line-{{ buffer_del.old_lineno }}">{{ buffer_del.old_lineno }}</a>
                                            </td>
                                            <td class="content {{ 'deletion' if buffer_insertions|length == 0 else 'change' }}">{{ buffer_del.content }}</td>
                                        {% else %}
                                            <td class="linenos">
                                            </td>
                                            <td class="content"></td>
                                        {% endif %}
                                        
                                        {% if buffer_ins %}
                                            <td class="linenos">
                                                <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ buffer_ins.new_lineno }}">{{ buffer_ins.new_lineno }}</a>
                                            </td>
                                            <td class="content {{ 'insertion' if buffer_deletions|length == 0 else 'change' }}">{{ buffer_ins.content }}</td>
                                        {% else %}
                                            <td class="linenos">
                                            </td>
                                            <td class="content"></td>
                                        {% endif %}
                                    </tr>
                                {% endfor %}
                                
                                {# .clear() empties the buffer. Since this requires {{}}
                                 # brackets instead of {%%}, this line will print the value
                                 # of "buffer_deletions" which is "None".
                                 # "or ''" is a hack for printing an empty line instead of "None".
                                 #}
                                {{ buffer_deletions.clear() or '' }}
                                {{ buffer_insertions.clear() or '' }}
                            {% endmacro %}
                            
                            <tr class="header">
                                <td colspan=4>{{ hunk.header }}</td>
                            </tr>
                            
                            {% for line in hunk.lines %}
                                {% if line.old_lineno < 0 %}
                                    {{ buffer_insertions.append(line) or '' }}
                                {% endif %}
                                
                                {% if line.new_lineno < 0 %}
                                    {{ buffer_deletions.append(line) or '' }}
                                {% endif %}
                                
                                {% if line.old_lineno >= 0 and line.new_lineno >= 0 %}
                                
                                    {# Unload buffer #}
                                    {{ print_buffer(buffer_deletions, buffer_insertions) }}
                                    
                                    {# Insert the unchanged line. #}
                                    <tr class="ssdiff">
                                        <td class="linenos">
                                            <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.parents[0].id, tree_path=patch.delta.old_file.path) }}#line-{{ line.old_lineno }}">{{ line.old_lineno }}</a>
                                        </td>
                                        <td class="content">{{ line.content }}</td>
                                        
                                        <td class="linenos">
                                            <a href="{{ url('tree_path', repository=repository[:-4], revision=commit.id, tree_path=patch.delta.new_file.path) }}#line-{{ line.new_lineno }}">{{ line.new_lineno }}</a>
                                        </td>
                                        <td class="content">{{ line.content }}</td>
                                    </tr>
                                {% endif %}
                            {% endfor %}
                            
                            {# Empty remaining buffer. There is a non-empty buffer if we did
                             # not find an unchanged line, for example when context_lines=0.
                             #}
                            {{ print_buffer(buffer_deletions, buffer_insertions) }}
                        {% endif %}
                    
                    {% endfor %}
                    
                </table>
            </details>
            
            <hr/>
        
        {% endfor %}
        
        {% endif %}
    </div>

{% endblock %}