Fork of patx/hglab.
tokenmess/hglab
fixes #4 View source code at a certain commit.
Commit 125c151c5319 · Harrison Erd · 2026-05-04 18:42 -0400
Comments
No comments yet.
Diff
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -43,7 +43,9 @@
REF_TYPE_BRANCH = "branch"
REF_TYPE_BOOKMARK = "bookmark"
REF_TYPE_TIP = "tip"
-REF_TYPES = {REF_TYPE_BRANCH, REF_TYPE_BOOKMARK, REF_TYPE_TIP}
+REF_TYPE_COMMIT = "commit"
+REF_TYPES = {REF_TYPE_BRANCH, REF_TYPE_BOOKMARK, REF_TYPE_TIP, REF_TYPE_COMMIT}
+PULL_REQUEST_REF_TYPES = {REF_TYPE_BRANCH, REF_TYPE_BOOKMARK, REF_TYPE_TIP}
REF_QUERY_KEYS = {"ref", "ref_type", "ref_value"}
REF_VALUE_SEPARATOR = "|"
SCRIPT_STYLE_RE = re.compile(r"(?is)<(script|style)\b[^>]*>.*?</\1>")
@@ -565,7 +567,7 @@
"repo_owner_username": repo["owner_username"],
"repo_name": repo["name"],
"target_url": f"/{repo['owner_username']}/{repo['name']}/commits/{commit['node']}",
- "target_label": commit["node"],
+ "target_label": commit["short_node"],
"summary": "committed",
"detail": text_preview(commit["summary"]),
}
@@ -1215,7 +1217,7 @@
def commit_log(path, limit=50, revision=None):
if revision == NULL_REV:
return []
- template_arg = "{rev}\\x1f{node|short}\\x1f{author|person}\\x1f{date|isodate}\\x1f{desc|firstline}\\x1e"
+ template_arg = "{rev}\\x1f{node}\\x1f{node|short}\\x1f{author|person}\\x1f{date|isodate}\\x1f{desc|firstline}\\x1e"
args = ["log", "-l", str(limit), "--template", template_arg]
if revision:
args[1:1] = ["-r", ancestors_revset(revision)]
@@ -1230,15 +1232,16 @@
if not record:
continue
parts = record.split("\x1f")
- if len(parts) != 5:
+ if len(parts) != 6:
continue
commits.append(
{
"rev": parts[0],
"node": parts[1],
- "author": parts[2],
- "date": parts[3],
- "summary": parts[4],
+ "short_node": parts[2],
+ "author": parts[3],
+ "date": parts[4],
+ "summary": parts[5],
}
)
return commits
@@ -1337,6 +1340,26 @@
return info
+def commit_ref(path, revision):
+ revision = (revision or "").strip()
+ if not REV_RE.match(revision) or revision == NULL_REV:
+ raise ValueError("Commit not found.")
+ info = revision_info(path, revision)
+ if not info:
+ raise ValueError("Commit not found.")
+ info.update(
+ {
+ "type": REF_TYPE_COMMIT,
+ "name": info["node"],
+ "label": f"commit {info['short_node']}",
+ "active": False,
+ "closed": False,
+ "is_default": False,
+ }
+ )
+ return info
+
+
def list_repo_branches(path):
template_arg = (
"{branch}\\x1f{node}\\x1f{node|short}\\x1f{rev}\\x1f{active}\\x1f{closed}\\x1f"
@@ -1427,6 +1450,8 @@
ref_name = ref_name or ""
if ref_type == REF_TYPE_TIP:
return tip_ref(path)
+ if ref_type == REF_TYPE_COMMIT:
+ return commit_ref(path, ref_name)
if ref_type == REF_TYPE_BRANCH:
for branch in list_repo_branches(path):
if branch["name"] == ref_name:
@@ -1448,16 +1473,16 @@
return REF_VALUE_SEPARATOR.join((str(repo_id), ref_type, quote(ref_name or "", safe="")))
-def parse_ref_option_value(value):
+def parse_ref_option_value(value, allowed_types=REF_TYPES):
parts = (value or "").split(REF_VALUE_SEPARATOR, 1)
- if len(parts) != 2 or parts[0] not in REF_TYPES:
+ if len(parts) != 2 or parts[0] not in allowed_types:
raise ValueError("Invalid ref.")
return parts[0], unquote(parts[1])
def parse_source_ref_option_value(value):
parts = (value or "").split(REF_VALUE_SEPARATOR, 2)
- if len(parts) != 3 or parts[1] not in REF_TYPES:
+ if len(parts) != 3 or parts[1] not in PULL_REQUEST_REF_TYPES:
raise ValueError("Invalid source ref.")
try:
repo_id = int(parts[0])
@@ -1523,6 +1548,8 @@
return f"branch {ref_name}"
if ref_type == REF_TYPE_BOOKMARK:
return f"bookmark {ref_name}"
+ if ref_type == REF_TYPE_COMMIT:
+ return f"commit {ref_name[:12]}" if ref_name else "commit"
return "tip"
@@ -2058,6 +2085,7 @@
"commit_detail.tpl",
repo=repo,
commit=commit,
+ commit_source_ref=commit_ref(path, commit["node"]),
diff=commit_diff(path, commit["node"]),
comments=list_commit_comments(repo["id"], commit["node"]),
comment_value=comment_value,
@@ -2706,7 +2734,10 @@
if request.method == "POST":
try:
source_repo_id, source_ref_type, source_ref_name = parse_source_ref_option_value(selected_source_ref)
- target_ref_type, target_ref_name = parse_ref_option_value(selected_target_ref)
+ target_ref_type, target_ref_name = parse_ref_option_value(
+ selected_target_ref,
+ allowed_types=PULL_REQUEST_REF_TYPES,
+ )
except ValueError as exc:
return render(
"new_pull_request.tpl",
diff --git a/templates/commit_detail.tpl b/templates/commit_detail.tpl
--- a/templates/commit_detail.tpl
+++ b/templates/commit_detail.tpl
@@ -15,12 +15,15 @@
<p class="muted">Commit {{commit["short_node"]}} · {{commit["author"]}} · {{commit["date"]}}</p>
<dl class="meta-list">
<dt>Changeset</dt>
- <dd><code>{{commit["node"]}}</code></dd>
+ <dd>
+ <code>{{commit["node"]}}</code>
+ </dd>
% if commit["parents"]:
<dt>Parents</dt>
<dd><code>{{commit["parents"]}}</code></dd>
% end
</dl>
+ <p class="muted"><a href="{{url_with_ref('/' + repo['owner_username'] + '/' + repo['name'] + '/src', commit_source_ref, True)}}">View source at this commit</a></p>
% if "\n" in commit["description"]:
<pre class="readme">{{commit["description"]}}</pre>
% end
diff --git a/templates/commits.tpl b/templates/commits.tpl
--- a/templates/commits.tpl
+++ b/templates/commits.tpl
@@ -16,7 +16,7 @@
<ul class="commit-list">
% for commit in commits:
<li>
- <code><a href="{{url_with_ref('/' + repo['owner_username'] + '/' + repo['name'] + '/commits/' + commit['node'], selected_ref)}}">{{commit["node"]}}</a></code>
+ <code><a href="{{url_with_ref('/' + repo['owner_username'] + '/' + repo['name'] + '/commits/' + commit['node'], selected_ref)}}">{{commit["short_node"]}}</a></code>
<div>
<strong>{{commit["summary"]}}</strong>
<small>{{commit["author"]}} · {{commit["date"]}}</small>