Fork of patx/hglab.

fixes #4 View source code at a certain commit.

Commit 125c151c5319 · Harrison Erd · 2026-05-04 18:42 -0400

Changeset
125c151c531913761fa469fdf7bcdfdfa6674fd1

View source at this commit

Comments

No comments yet.

Log in to comment

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>