Resolve name and email from mailmap

The mailmap file is consulted to obtain the canonical name/email of an
author or committer of a commit, or a tagger of a tag.

Signed-off-by: Sebastian <sebastian@sebsite.pw>
This commit is contained in:
Sebastian 2022-11-01 20:01:09 -04:00 committed by Drew DeVault
parent 4436def286
commit 2369d4aa22
10 changed files with 54 additions and 25 deletions

View File

@ -20,17 +20,19 @@ from srht.validation import Validation
porcelain = Blueprint("api_porcelain", __name__)
# See also gitsrht-update-hook/types.go
def commit_to_dict(c):
def commit_to_dict(c, repo):
author = repo.author(c)
committer = repo.committer(c)
return {
"id": str(c.id),
"short_id": c.short_id,
"author": {
"email": c.author.email,
"name": c.author.name,
"email": author.email,
"name": author.name,
},
"committer": {
"email": c.committer.email,
"name": c.committer.name,
"email": committer.email,
"name": committer.name,
},
"timestamp": commit_time(c),
"message": c.message,
@ -153,7 +155,7 @@ def repo_commits_GET(username, reponame, ref, path):
next_id = str(commits[-1].id)
return {
"next": next_id,
"results": [commit_to_dict(c) for c in commits],
"results": [commit_to_dict(c, repo) for c in commits],
# TODO: Track total commits per repo per branch
"total": -1,
"results_per_page": commits_per_page

View File

@ -503,7 +503,7 @@ def log(owner, repo, ref, path):
has_more = commits and len(commits) == 21
author_emails = set((commit.author.email for commit in commits[:20]))
author_emails = set((repo.author(commit).email for commit in commits[:20]))
authors = {user.email:user for user in User.query.filter(User.email.in_(author_emails)).all()}
return render_template("log.html", view="log",
owner=owner, repo=repo, ref=ref, path=path.split("/"),
@ -671,7 +671,7 @@ def refs_rss(owner, repo):
def _ref_sort_key(ref):
target = git_repo.get(ref.target)
author = target.author if hasattr(target, 'author') else target.get_object().author
author = repo.author(target)
return author.time + author.offset
references = sorted(references, key=_ref_sort_key, reverse=True)[:20]

View File

@ -1,6 +1,6 @@
from collections import deque
from datetime import datetime, timedelta, timezone
from pygit2 import Repository as GitRepository, Tag
from pygit2 import Repository as GitRepository, Mailmap, Tag
from markupsafe import Markup, escape
from stat import filemode
import pygit2
@ -98,6 +98,7 @@ def get_log(git_repo, commit, path="", commits_per_page=20, until=None):
class Repository(GitRepository):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._mailmap = Mailmap.from_repository(self)
def __enter__(self):
return self
@ -122,6 +123,18 @@ class Repository(GitRepository):
else:
return None
def author(self, obj):
sig = obj.author if hasattr(obj, "author") else obj.get_object().author
return self._mailmap.resolve_signature(sig)
def committer(self, obj):
sig = obj.committer if hasattr(obj, "committer") else obj.get_object().committer
return self._mailmap.resolve_signature(sig)
def tagger(self, obj):
sig = obj.tagger if hasattr(obj, "tagger") else obj.get_object().tagger
return self._mailmap.resolve_signature(sig)
@property
def is_empty(self):
return len(self.raw_listall_branches(pygit2.GIT_BRANCH_LOCAL)) == 0

View File

@ -45,7 +45,7 @@ def ref_to_item(repo, reference):
with GitRepository(repo.path) as git_repo:
target = git_repo.get(reference.target)
author = target.author if hasattr(target, 'author') else target.get_object().author
author = repo.author(target)
time = aware_time(author).strftime(RFC_822_FORMAT)
url = ref_url(repo, reference)
description = target.message.strip().replace("\n", "<br />")
@ -64,7 +64,8 @@ def commit_to_item(repo, commit):
time = aware_time(commit.author).strftime(RFC_822_FORMAT)
url = commit_url(repo, commit)
title, description = commit_title_description(commit)
author = f"{commit.author.email} ({commit.author.name})"
author = repo.author(commit)
author = f"{author.email} ({author.name})"
element = ET.Element("item")
ET.SubElement(element, "title").text = title

View File

@ -27,12 +27,13 @@ pre, body {
repo=repo.name,
ref=ref)}}"
>{{commit.id.hex[:8]}}</a> &mdash;
{% set author_user = lookup_user(commit.author.email) %}
{% set author = repo.author(commit) %}
{% set author_user = lookup_user(author.email) %}
{% if author_user %}
<a href="{{url_for("public.user_index",
username=author_user.username)}}">{{commit.author.name}}</a>
username=author_user.username)}}">{{author.name}}</a>
{% else %}
{{commit.author.name}}
{{author.name}}
{% endif %}
{{trim_commit(commit.message)}}
<span class="text-muted">

View File

@ -24,12 +24,13 @@ pre {
repo=repo.name,
ref=ref)}}"
>{{commit.id.hex[:8]}}</a> &mdash;
{% set author_user = lookup_user(commit.author.email) %}
{% set author = repo.author(commit) %}
{% set author_user = lookup_user(author.email) %}
{% if author_user %}
<a href="{{url_for("public.user_index",
username=author_user.username)}}">{{commit.author.name}}</a>
username=author_user.username)}}">{{author.name}}</a>
{% else %}
{{commit.author.name}}
{{author.name}}
{% endif %}
{{trim_commit(commit.message)}}
<span class="text-muted">

View File

@ -38,11 +38,11 @@
<h4 style="margin-bottom: 0.5rem">
{% if isinstance(tag, pygit2.Commit) %}
{% set refname = commit.id.hex %}
{% set author = commit.author %}
{% set author = repo.author(commit) %}
{{ref[len("refs/tags/"):]}}
{% else %}
{% set refname = tag.raw_name %}
{% set author = tag.tagger %}
{% set author = repo.tagger(tag) %}
<a href="{{url_for("repo.ref",
owner=repo.owner.canonical_name,
repo=repo.name,

View File

@ -16,12 +16,13 @@
repo=repo.name,
ref=ref)}}"
>{{commit.id.hex[:8]}}</a> &mdash;
{% set author_user = lookup_user(commit.author.email) %}
{% set author = repo.author(commit) %}
{% set author_user = lookup_user(author.email) %}
{% if author_user %}
<a href="{{url_for("public.user_index",
username=author_user.username)}}">{{commit.author.name}}</a>
username=author_user.username)}}">{{author.name}}</a>
{% else %}
{{commit.author.name}}
{{author.name}}
{% endif %}
{{trim_commit(commit.message)}}
<span class="text-muted">

View File

@ -93,12 +93,13 @@ endif %}{% endfor %}
>{{c.id.hex[:8]}}</a>
{% endif %}
&mdash;
{% set author_user = lookup(c.author.email) %}
{% set author = repo.author(c) %}
{% set author_user = lookup(author.email) %}
{% if author_user %}
<a href="{{url_for("public.user_index",
username=author_user.username)}}">{{c.author.name}}</a>
username=author_user.username)}}">{{author.name}}</a>
{% else %}
{{c.author.name}}
{{author.name}}
{% endif %}
<small class="pull-right">
<a

View File

@ -148,5 +148,14 @@ class Repository(Base):
self._git_repo = GitRepository(self.path)
return self._git_repo
def author(self, obj):
return self.git_repo.author(obj)
def committer(self, obj):
return self.git_repo.committer(obj)
def tagger(self, obj):
return self.git_repo.tagger(obj)
from gitsrht.types.artifact import Artifact
from gitsrht.types.sshkey import SSHKey