Skip to content

bug(setup-worktree): stale submodule blocks creation, requires destructive sync #19

@WesleyMFrederick

Description

@WesleyMFrederick

Problem

When .claude submodule has uncommitted changes (e.g., behind hub by N commits), the worktree script's pre-flight check (git diff-index --quiet HEAD) rejects the dirty working tree. Recovery requires git reset --hard on the submodule — a destructive, non-reversible operation.

Reproduction Steps

  1. .claude submodule falls behind hub by 25 commits (normal drift)
  2. Run .claude/scripts/setup-worktree.sh jact bug-fixes
  3. Phase 1 pre-flight fails: "Working directory is not clean"
  4. User must manually sync submodule (stash, pull, resolve conflicts)
  5. In this session: required git reset --hard FETCH_HEAD to resolve

Root Cause

Script's pre-flight (line 33-37) treats submodule drift as a dirty working tree but offers no recovery path. Phase 4.5 (line 94-107) syncs the submodule in the new worktree but not the source repo where pre-flight runs.

Architecture Principles Violated

Baseline violates:

  • ^error-recovery: No graceful rollback or recovery from stale submodule state. Only escape is destructive reset --hard.
  • ^backup-creation: No backup before destructive submodule sync. Local submodule commits could be lost.
  • ^dry-run-capability: No preview of what sync will do before executing destructive operation.

Ideal incorporates:

  • ^error-recovery: Use git pull --ff-only which fails safely if diverged (no data loss). Fall back to user prompt on conflict.
  • ^backup-creation: Stash or branch local submodule changes before sync.
  • ^dry-run-capability: Show what commits will be pulled and ask before proceeding.

Expected Behavior

Script detects stale submodule in pre-flight, offers safe sync via --ff-only (fails safely if diverged), and only proceeds with user confirmation for non-fast-forward cases.

Related

Note

The submodule drifting behind the hub is a common, expected state. The script should handle it as a normal case, not an error.


Acceptance Criteria

  • Script detects stale submodule as distinct from other dirty-tree states
  • Offers safe sync (--ff-only) with user confirmation
  • Falls back to user prompt when fast-forward not possible
  • Never performs destructive operations without user approval
  • Existing pre-flight for actual dirty files still works

Definition of Done

  • Reproduction confirmed
  • Script updated with safe submodule sync path
  • End-to-end test with stale submodule succeeds
  • Committed with conventional commit

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions