Files
Gitea-Tools/issue_branch_ownership.py
T
sysadminandClaude Opus 4.8 80aa295635 feat: non-destructive branch recovery after lost issue locks (Closes #440)
Implements the #420 recovery umbrella: keyed persistent issue locks with
own-branch adoption, structured branch ownership parsing, create_pr lock
resolution after MCP restart, and workflow docs forbidding destructive
branch deletion as the default recovery path.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-07-07 16:42:23 -04:00

31 lines
1.0 KiB
Python

"""Structured issue/branch ownership evidence (#440).
Author branches must follow ``(fix|feat|docs|chore)/issue-<n>-<desc>``. Duplicate-work
and recovery gates use this parser instead of broad substring checks like
``issue-420`` inside unrelated names (for example ``issue-4200``).
"""
from __future__ import annotations
import re
IMPLEMENTATION_BRANCH_RE = re.compile(
r"^(?:fix|feat|docs|chore)/issue-(\d+)(?:-.+)?$"
)
def parse_tracked_issue_number(branch_name: str) -> int | None:
"""Return the issue number encoded in a canonical author branch name."""
text = (branch_name or "").strip()
if not text:
return None
match = IMPLEMENTATION_BRANCH_RE.match(text)
if not match:
return None
return int(match.group(1))
def branch_tracks_issue(branch_name: str, issue_number: int) -> bool:
"""True when ``branch_name`` structurally belongs to ``issue_number``."""
parsed = parse_tracked_issue_number(branch_name)
return parsed == issue_number if parsed is not None else False