mirror of
https://github.com/max-sixty/worktrunk.git
synced 2026-09-14 20:00:38 +08:00
f57fac365b
Release v0.72.0 — 55 commits since v0.71.0. Minor bump: `cargo semver-checks` reports 5 breaking library changes, so patch is disallowed pre-1.0. ## Headline changes - **`wt merge` / `wt step push` no longer autostash the target worktree** (#3703). Both strategies now advance the target through one `advance_target` — a compare-and-swap `update-ref`, then `read-tree -m -u` in the target worktree — so `refs/stash` is never entered and staged changes stay staged. - **Forge classification returns to brand-in-hostname** (#3673), reverting the exact-DNS-label rule 0.71.0 shipped. `github-enterprise.acme.com` and friends resolve again with no config. - **`[projects."…"]` keys match by `*` pattern and carry forge settings** (#3701), so one user-config entry covers every repository on a self-hosted host. - **A published JSON Schema for `wt list --format=json` schema 2** (#3747), plus machine-readable approval state and `branch_outcome` (#3710). Full detail in `CHANGELOG.md`. ## One fix made during the release cut The release audit surfaced a gap this release's own `advance_target` rewrite introduced, fixed here rather than deferred: **`wt merge` / `wt step push` now refuse a target worktree parked mid-operation.** The target sync is a two-tree merge, which refuses an unmerged index but *not* a stopped cherry-pick or rebase whose conflict has already been staged. A target paused between steps could therefore have the push range written into it, and the user's `--continue` would commit the synced tree as the step's result. The old fast-forward path got this check for free from `receive.denyCurrentBranch=updateInstead`, which refused any unclean target outright; both strategies now ask directly, and the refusal names the worktree holding the operation. `test_push_refuses_target_mid_operation` covers it in both shapes a stopped operation can take, and both are mutation-verified. With the gate disabled, the push succeeds and writes `feature.txt` into the mid-cherry-pick worktree. The rebase case was added in response to review feedback on this PR, and pins a second dependency. A rebase detaches HEAD, so `git worktree list --porcelain` reports the target with no branch and `worktree_for_branch` finds it only because `finalize_worktree` backfills from `rebase-merge/head-name`. That makes the rebase arm the one place this guarantee rests on a helper of ours rather than on git — the fast-forward path it replaced got the refusal from `find_shared_symref`. With the backfill disabled, `wt step push` succeeds against a worktree parked mid-rebase while the cherry-pick case still passes, so the gap was real. ## Validation - Local gate green: `cargo run -- hook pre-merge --yes` — 4570 tests, clippy, fmt, doc sync. - Cross-platform nightly green on the cut-from tip `3817df079` (run 31133551751): full nextest matrix on linux/macOS/Windows, feature-powerset, all three release triples, nix-flake, minimal-versions, unused-deps, crate-build, link-check. - Changelog verified entry-by-entry against the diffs by an independent pass; every one of the 55 commits either maps to an entry or is a documented skip. - `main` advanced during the CI wait. #3762 ships in this release and now has a changelog entry; the other two commits that landed (#3758, #3749) touch only `.github/`. - Data-loss surface reviewed by four independent finders over the cumulative diff. One further finding — a pre-0.72 `approvals.toml` key containing `*` being reinterpreted as a wildcard on upgrade — was reviewed and accepted as out of scope for this release. > _This was written by Claude Code on behalf of max-sixty_ --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>