From 2a67bb9e8ce2cd0c684f6d0b78ee19c0494d09ea Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Sat, 3 Oct 2026 19:50:43 +0530 Subject: [PATCH] fix(worktree): name what changed when attended reclaim keeps a tree Gate finding (Low, quality): the "state changed since audit" message printed only the fresh classification reason. When the branch or the untracked list had changed, the verdict was still reap, so the message read "state changed since audit: clean and fully merged/pushed", which explains nothing. It now names the field that changed (verdict / untracked files / branch) and gives the current reason. Also fixes the stale "`remove --force` refuses" comment: removal is now usually a plain `worktree remove`. The dead `if not refreshed` guard was dropped in the previous commit. --- hermes_cli/worktree_gc.py | 11 +++++++---- .../hermes_cli/test_worktree_reclaim_revalidation.py | 4 +++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/hermes_cli/worktree_gc.py b/hermes_cli/worktree_gc.py index d0f17a25aa..0aca7ff515 100644 --- a/hermes_cli/worktree_gc.py +++ b/hermes_cli/worktree_gc.py @@ -308,9 +308,12 @@ def reclaim_worktrees( verdict, reason, untracked = _classify_tree( _ops, repo_root, entry, merge_cache, remote_heads) branch = _git(["branch", "--show-current"], cwd=record.path, timeout=5) - if (verdict != record.verdict or untracked != record.untracked - or branch.returncode != 0 or branch.stdout.strip() != record.branch): - actions.append(f"kept {record.name} (state changed since audit: {reason})") + changed = ("verdict" if verdict != record.verdict + else "untracked files" if untracked != record.untracked + else "branch" if branch.returncode != 0 or branch.stdout.strip() != record.branch + else "") + if changed: + actions.append(f"kept {record.name} (state changed since audit: {changed}; now {reason})") continue except Exception as exc: actions.append(f"kept {record.name} (could not revalidate: {exc})") @@ -322,7 +325,7 @@ def reclaim_worktrees( continue actions.append(f"archived {len(record.untracked)} untracked file(s) → {archive}") - # Dead-pid locks must be unlocked or `remove --force` refuses. + # Dead-pid locks must be unlocked or `worktree remove` refuses. with contextlib.suppress(Exception): _git(["worktree", "unlock", record.path], cwd=repo_root, timeout=10) try: diff --git a/tests/hermes_cli/test_worktree_reclaim_revalidation.py b/tests/hermes_cli/test_worktree_reclaim_revalidation.py index bf95449ff3..8271ddd5da 100644 --- a/tests/hermes_cli/test_worktree_reclaim_revalidation.py +++ b/tests/hermes_cli/test_worktree_reclaim_revalidation.py @@ -45,7 +45,9 @@ def test_attended_reclaim_preserves_work_added_after_audit(repository, kind): assert next(record for record in records if record.path == str(tree)).verdict == "reap" _add_work(tree, kind) - reclaim_worktrees(str(root), records=records) + assert reclaim_worktrees(str(root), records=records) == [ + "kept scratch (state changed since audit: verdict; now uncommitted tracked changes (real work))" + if kind == "edit" else "kept scratch (state changed since audit: verdict; now unpushed commits not found upstream)"] assert tree.is_dir() assert (tree / "README.md").read_text(encoding="utf-8") == "new work after audit\n"