fix(issue-21): review ec50fbe7 R6 - the unpushed check covers HEAD and every local ref (tags included, stash excluded) in both submodule checks

Both unpushed checks in lib_py/worktree.py - `submodule foreach` over the
initialised checkouts and the direct `--git-dir` walk over the repositories
under the worktree's modules/ - used `HEAD --branches --not --remotes`. A
commit made on a submodule's detached HEAD and kept only by a tag is reachable
from neither, the top-level status stays clean, and worktree_remove.sh then
deleted the repository with its single --force (exit 0).

Both checks now share one rev list, UNPUSHED_REVS = HEAD --exclude=refs/stash
--all --not --remotes: HEAD and every local ref (branches, tags, notes, ...)
minus remote-tracking refs. refs/stash stays out of it because the stash check
(stash list / reflog) owns it, so a stash is reported once, as 'stashes'. As
intended, a local-only note is now protected too. The stash, error, partial
repository and dirty checks are unchanged.

Tests W6l (tag-only commit; initialised submodule and deinit'd repository) and
W6m (annotated tag). The helper header, the stop SKILL.md and the design doc
state the wider rule.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
This commit is contained in:
GodopuandClaude Opus 5 committed 2026-09-14 20:11:18 +00:00
1 parent c7c559b7aa
commit 25f4be3359
5 files changed
+59 -10

No files matched your search

@@ -10,8 +10,8 @@
# session under it unless --stop; (3) no open job of those sessions (the
# delegate job of a session --stop will stop is cancelled by stop itself);
# (4) clean tree, submodules included; (5) submodules: nothing modified and no
# commit that is on no remote (HEAD included - a submodule is on a detached
# HEAD) and no stash - in every repository under the worktree's modules/,
# commit reachable from HEAD or any local ref (tags included - a submodule is
# on a detached HEAD) that is on no remote, and no stash - in every repository under the worktree's modules/,
# initialised or not. (4) and (5) run again right before the removal, after
# --stop: a session that is being stopped can still write, commit or stash.
# Removal is plain, or - when the worktree holds submodule state, which