submit and author resubmits: the commit must be a hash git knows (checked in the author's workdir or the Logbook checkout) and is stored in full; HEAD, placeholders and unknown hashes are refused

This commit is contained in:
KeelrLeek committed 2026-10-06 21:20:45 -05:00
1 parent a92efdad45
commit eb948ddda1
3 files changed
+198 -166

No files matched your search

+3
View File
@@ -761,6 +761,7 @@ class Harbor(WorkMixin, ExtrasMixin, FlowMixin, LaunchMixin):
if not reviewers:
raise HarborError("no reviewer: name one, or set reviewers in the project file")
canonical = parse_scope(scope)[0] if scope else None
commit = self.resolve_commit(author, commit)
def do(c):
now = self.now()
@@ -822,6 +823,8 @@ class Harbor(WorkMixin, ExtrasMixin, FlowMixin, LaunchMixin):
self.require_running(agent, "move review items")
if to_state == "landed":
self.check_landing_policy(item_id)
if is_author and commit:
commit = self.resolve_commit(agent, commit)
def do(c):
now = self.now()
+23
View File
@@ -39,6 +39,29 @@ def _git(workdir, *args):
class FlowMixin:
def resolve_commit(self, agent, commit):
"""The full hash of a commit an item names, checked in agent's workdir (or the Logbook's decomp checkout).
A placeholder ('HEAD', 'PLACEHOLDER') or a hash git does not know is refused; without any git checkout to
ask, the value is kept as given."""
if not commit:
return commit
commit = str(commit).strip()
spec = next((a for a in self.project.agents if a["name"] == agent), {})
places = [spec.get("workdir"), (self.project.logbook or {}).get("decomp")]
repos = [p for p in places if p and (Path(p) / ".git").exists()]
if not repos:
return commit
if not re.fullmatch(r"[0-9a-fA-F]{7,40}", commit):
raise HarborError(f"commit {commit!r} is not a hash: give the commit's hash (git rev-parse HEAD), "
"not a branch name, HEAD or a placeholder")
for repo in repos:
try:
return _git(repo, "rev-parse", "--verify", "--quiet", f"{commit}^{{commit}}").strip()
except (RuntimeError, subprocess.TimeoutExpired):
continue
raise HarborError(f"commit {commit} is not in the repository: commit your work first and give the hash "
"git rev-parse HEAD prints")
def worktree_change(self, agent):
"""(mtime, path) of the most recently modified uncommitted file in agent's worktree, or None."""
spec = next((a for a in self.project.agents if a["name"] == agent), {})