home » zplus/clif.git
ID: 7973425250783d78aa5476c033d06241f26caee8
342 lines — 16K — 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 ID</b>
                    </td>
                    <td>
                        {{ commit.id }}
                    </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_SHOW_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">{{ patch.delta.new_file.path }}</td>
                        <td class="lines">{{ patch.line_stats[1] + patch.line_stats[2] }}</td>
                        <td class="histogram">
                            <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>
                        </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">
            <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="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>
        
        {% for patch in diff %}
        
            <table class="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
                 # 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)
                 #}
                <thead>
                    <tr>
                        <td colspan="4">
                            {% 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 patch.delta.status == 1 %}
                                <b title="Added">A</b> {{ patch.delta.new_file.path }}
                            {% endif %}
                            
                            {% if patch.delta.status == 2 %}
                                <b title="Deleted">D</b> {{ patch.delta.old_file.path }}
                            {% endif %}
                            
                            {% if patch.delta.status == 3 %}
                                <b title="Modified">M</b> {{ patch.delta.new_file.path }}
                            {% endif %}
                            
                            {% if patch.delta.status == 4 %}
                                <b title="Renamed">R</b> {{ patch.delta.old_file.path }} -> {{ patch.delta.new_file.path }}
                            {% endif %}
                            
                            {% if patch.delta.status == 5 %}
                                <b title="Copied">C</b> {{ patch.delta.old_file.path }} {{ patch.delta.new_file.path }}
                            {% endif %}
                        </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 patch.delta.status == 1 %}
                                new file mode: {{ patch.delta.new_file.mode|filemode }}
                            {% elif patch.delta.status == 2 %}
                                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>
                </thead>
                <tbody>
                    {% 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 ####}
                        
                        {% 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="lineno">
                                        {% if line.old_lineno >= 0 %}
                                            {{ line.old_lineno }}
                                        {% endif %}
                                    </td>
                                    <td class="lineno">
                                        {% if line.new_lineno >= 0 %}
                                            {{ line.new_lineno }}
                                        {% endif %}
                                    </td>
                                    <td class="origin">{{ line.origin }}</td>
                                    <td class="content">{{ line.content }}</td>
                                </tr>
                            {% endfor %}
                        {% endif %}
                        
                        {#### SSDIFF mode ####}
                        
                        {% if mode == 'ssdiff' %}
                            {% 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="lineno">
                                                {{ buffer_del.old_lineno }}
                                            </td>
                                            <td class="content {{ 'deletion' if buffer_insertions|length == 0 else 'change' }}">{{ buffer_del.content }}</td>
                                        {% else %}
                                            <td class="lineno">
                                            </td>
                                            <td class="content"></td>
                                        {% endif %}
                                        
                                        {% if buffer_ins %}
                                            <td class="lineno">
                                                {{ buffer_ins.new_lineno }}
                                            </td>
                                            <td class="content {{ 'insertion' if buffer_deletions|length == 0 else 'change' }}">{{ buffer_ins.content }}</td>
                                        {% else %}
                                            <td class="lineno">
                                            </td>
                                            <td class="content"></td>
                                        {% endif %}
                                    </tr>
                                {% endfor %}
                                
                                {# .clear() empties the buffer. However since it 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>
                            
                            {% set buffer_deletions = [] %}
                            {% set buffer_insertions = [] %}
                            
                            {% 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) }}
                                    
                                    <tr class="ssdiff">
                                        <td class="lineno">
                                            {{ line.old_lineno }}
                                        </td>
                                        <td class="content">{{ line.content }}</td>
                                        
                                        <td class="lineno">
                                            {{ line.new_lineno }}
                                        </td>
                                        <td class="content">{{ line.content }}</td>
                                    </tr>
                                {% endif %}
                            {% endfor %}
                            
                            {# Empty remaining buffer #}
                            {{ print_buffer(buffer_deletions, buffer_insertions) }}
                        {% endif %}
                    
                    {% endfor %}
                </tbody>
                
            </table>
        
        {% endfor %}
    </div>

{% endblock %}