Browse Source

Added structured commit diff display

main
root 5 months ago
parent
commit
8392d3d297
  1. 3
      README.md
  2. 37
      cutegit/app.py
  3. 41
      cutegit/templates/repository/diff.html
  4. 17
      cutegit/views.py

3
README.md

@ -28,8 +28,7 @@ $ FLASK_ENV=cutegit:app flask run
- [Core] Login / Logout for accessing private repositories
- [Git] ~~metadata (branches, default branch, commit count)~~
- [Git] commit list (short messages, hashes, details blocks to full commit message)
- [Git] raw commit diff display
- [Git] structured commit diff display
- [Git] ~~structured commit diff display~~
- [Git] raw object display
- [Git] formatted object display
- [Git] ~~README.md auto-render~~

37
cutegit/app.py

@ -1,8 +1,6 @@
from flask import render_template, redirect, url_for, flash, session
# noinspection PyUnresolvedReferences
from pygit2._pygit2 import Diff
from . import views
from .core import app
from .git.backend import get_git, group_by_category
@ -49,7 +47,7 @@ def commit_history(repo: str, reference: str):
@app.route('/~<string:repo>/<path:reference>^')
def ref(repo: str, reference: str):
"""Show commit diff for the given reference, or between the two references"""
"""Show commit diff for the given reference"""
repository = get_git().get_repository(repo)
if repository is None:
flash(f'No repository with name {repo}')
@ -61,17 +59,44 @@ def ref(repo: str, reference: str):
flash(f'Reference not found: {reference}')
return redirect(url_for('repository_index', repo=repo))
diff = repository.diff(commit, cached=True)
diff = repository.diff(commit.parents[0], commit)
return render_template('repository/diff.html', name=repo, repo=repository, commit=commit, diff=diff)
return render_template(
'repository/diff.html',
name=repo, repo=repository, ref=reference, commit=commit, diff=diff,
single=True,
)
@app.route('/~<string:repo>/<path:reference>^<path:other>')
def ref_group(repo: str, reference: str, other: str):
pass
repository = get_git().get_repository(repo)
if repository is None:
flash(f'No repository with name {repo}')
return redirect(url_for('homepage'))
try:
commit = repository.revparse_single(other)
other_commit = repository.revparse_single(reference)
except KeyError:
flash(f'Reference not found')
return redirect(url_for('repository_index', repo=repo))
diff = repository.diff(commit, other_commit)
return render_template(
'repository/diff.html',
name=repo, repo=repository, ref=reference, other=other, commit=commit, other_commit=other_commit, diff=diff,
single=False,
)
@app.route('/~<string:repo>/@<path:reference>:')
@app.route('/~<string:repo>/@<path:reference>:<path:git_path>')
def git_object(repo: str, reference: str, git_path: str = ''):
pass
@app.route('/~<string:repo>/@<path:reference>:<path:git_path>/raw')
def raw_git_object(repo: str, reference: str, git_path: str):
pass

41
cutegit/templates/repository/diff.html

@ -1,22 +1,55 @@
{% extends 'repository/_layout.html' %}
{% macro honk(header, lines) -%}
<span class="header">{{ header }}</span>
<code>
{%- for line in lines -%}
<span class="origin" style="width: 1rem; /* temporary */">{{ line.origin }}</span>{{ line.content }}
{%- endfor -%}
</code>
{%- endmacro %}
{% block content %}
<main>
<h2>{{ commit.message|short }}</h2>
<p>Commit #<span>{{ commit.hex }}</span>, the {{ commit.commit_time|date_iso8601 }}.</p>
<p>#<span>{{ commit.hex }}</span>, the {{ commit.commit_time|date_iso8601 }}.</p>
{% if not single %}
<p class="to">to</p>
<h2>{{ other_commit.message|short }}</h2>
<p>#<span>{{ other_commit.hex }}</span>, the {{ other_commit.commit_time|date_iso8601 }}</p>
{% endif %}
<p>
{{ diff.stats.files_changed }} files changed ({{ diff.stats.insertions }} additions,
{{ diff.stats.deletions }} deletions).
</p>
<section class="diff_objects">
{% for delta in diff.deltas %}
{% for patch in diff %}
{% set delta = patch.delta %}
<details>
<summary>
{% if delta.status == 1 %}{# 1 == added #}
{% endif %} -%}
Created {{ delta.new_file.path }}
{% elif delta.status == 2 %}{# 2 == deleted #}
Deleted {{ delta.old_file.path }}
{% elif delta.status == 3 %}{# 3 == content modified #}
Edited {{ delta.new_file.path }}
{% endif %}
</summary>
<section>
{% if delta.status == 2 %}
<p class="center">The file was deleted</p>
{% elif delta.is_binary %}
<p class="center">
Binary file (
<a href="{{ url_for('raw_git_object', repo, ref, delta.new_file.id) }}">open raw</a>
)
</p>
{% else %}
{{ patch|display_hunks|safe }}
{% endif %}
</section>
</details>
{% endfor %}
</section>

17
cutegit/views.py

@ -4,7 +4,8 @@ from time import time
from flask import current_app
from markdown import markdown
from pygit2 import Repository, Reference
from markupsafe import escape
from pygit2 import Repository, Reference, Patch
from .core import app
from .git.backend import count_commits
@ -79,3 +80,17 @@ def clone_url(repo: str) -> str:
def short_commit_msg(msg: str) -> str:
maybe_line = msg.splitlines()[:1]
return maybe_line[0] if len(maybe_line) > 0 else '(no commit message)'
@app.template_filter('display_hunks')
def display_hunks(patch: Patch) -> str:
res = '<pre>\n'
for hunk in patch.hunks:
res += f'<span class="header">{hunk.header}</span>\n<code>'
for line in hunk.lines:
res += f'<span class="change_type">{line.origin}</span>{escape(line.content)}'
res += '</code>'
res += '</pre>'
return res
Loading…
Cancel
Save