feat(josh-sync): add rename command for safe target renames

Adds `josh-sync rename <target>` (PE-12): safely rename a sync target's
name, subfolder, and/or subrepo_url in one resumable operation, editing
.josh-sync.yml and migrating its state-branch files atomically instead of
orphaning them. Bumps josh-sync to v2.3.0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNXgcFWVgSh3wkQS55cCX6
This commit is contained in:
2026-07-16 10:10:40 +01:00
co-authored by Claude Sonnet 5
parent c4bcbbdd4f
commit 27b0e2acaa
11 changed files with 1089 additions and 2 deletions
+12
View File
@@ -1,5 +1,17 @@
# Changelog
## 2.3.0
### Features
- **`josh-sync rename <target>` command** ([PE-12](https://linear.app/noqta-ai/issue/PE-12)): safely rename a target's `name`, `subfolder`, and/or `subrepo_url` in one resumable operation. Renaming by hand-editing `.josh-sync.yml` previously orphaned sync state (keyed by target name on the `josh-sync-state` branch) and left `josh_filter` stale after a subfolder move. `rename` now:
- Edits `.josh-sync.yml` (scoped to the one matching `targets[]` element) and re-derives `josh_filter` when `--subfolder` changes, then re-validates the result through `parse_config`.
- Migrates every state file under the target's `<name>/` prefix on `josh-sync-state` (per-branch state, `onboard.json`/legacy `adopt.json`) to the new name in a single commit, rewriting `.last_forward.josh_filter` where present.
- Validates the new `subrepo_url` is reachable and that no state already exists under a new name before writing anything; supports `--dry-run` and `--yes`.
- Uses a best-effort concurrency heuristic (recent commits on `josh-sync-state` for the target) to warn against renaming while a sync may be in flight; `--force` bypasses only this check — a destination-name state conflict or an unreachable new URL is never forceable.
- Is fully resumable: safe to re-run after an interruption at any point (config-already-updated, state-partially-migrated, or fully complete).
- Does not rename repositories on the git host, and does not rewrite the transient `auto-sync/mono-*`/`auto-sync/subrepo-*` branch names (they never carry the target name); a stale `auto-sync/import-<old-name>-*` staging branch from an abandoned onboarding is flagged with a warning only.
## 2.2.2
### Fixes