Conversation
Post-start commands should only run when a new worktree is created, not when switching to an existing worktree. This change ensures that post-start commands are correctly skipped in the latter case. Adds a newline after user input in `prompt_for_batch_approval` to prevent output interleaving.
The internal layout algorithm for `git branch --list` has been refined. This update reflects the changes in the implementation details, including: - Centralized `COLUMN_SPECS` registry. - Consolidated allocation loop. - Priority calculation and message expansion. Test assertions were also updated to align with the new logic.
These tests produce inconsistent output due to PTY buffering and background commands. They are temporarily disabled to prevent non-deterministic CI failures.
Fix rustdoc warnings by escaping angle brackets in doc comments: - Line 16: `<repo>` in Project Config path - Line 201: `<name>` in Vec type signature These were being interpreted as unclosed HTML tags, causing `cargo doc` to fail with rustdoc::invalid-html-tags errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add `cargo doc --no-deps` with `-Dwarnings` to local pre-merge checks to catch documentation issues before they fail in CI. This matches the CI workflow's doc step and would have caught the unclosed HTML tag issues that caused the earlier CI failure. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
5 tasks
max-sixty
added a commit
that referenced
this pull request
May 3, 2026
## Summary
A plain `wt <alias>` invocation used to spawn two `git rev-parse` forks
before alias dispatch: `--git-common-dir` from `init_command_log` and
the `prewarm_info` batch (`--is-inside-work-tree --show-toplevel
--git-dir --symbolic-full-name HEAD`) from `project_config_path`.
Visible in `[wt-trace]` output:
```
[wt-trace] cmd=\"git rev-parse --git-common-dir\" dur_us=10139
[wt-trace] cmd=\"git rev-parse --is-inside-work-tree --show-toplevel --git-dir --symbolic-full-name HEAD\" dur_us=10564
```
This adds `Repository::prewarm()` at the top of `main` (after the logger
is registered, before `init_command_log` and alias dispatch). One merged
`git rev-parse --git-common-dir --is-inside-work-tree --show-toplevel
--git-dir --symbolic-full-name HEAD` fork populates
`GIT_COMMON_DIR_CACHE` and the per-worktree git-discovery maps in one
shot. Both downstream callers then hit memory.
After the change, the trace shows one rev-parse and pure cache hits
afterward:
```
[wt-trace] span=\"prewarm\" dur_us=5917
[wt-trace] cmd=\"git rev-parse --git-common-dir --is-inside-work-tree --show-toplevel --git-dir --symbolic-full-name HEAD\" dur_us=5159
[wt-trace] span=\"init_command_log\" dur_us=39 # was 14144 (cache hit)
[wt-trace] span=\"project_config_load\" dur_us=25 # was 10714 (cache hit)
```
## Cache consolidation
Promoting the maps to process-wide is necessary for the optimization to
land: every `Repository::current()` builds a fresh `RepoCache`, so
writing to per-Repo maps from `prewarm` would warm a Repository nobody
used. While doing this, `worktree_roots` / `git_dirs` /
`current_branches` move out of `RepoCache` to `LazyLock<DashMap>`
statics next to `GIT_COMMON_DIR_CACHE`. Per-`RepoCache` scoping was a
historical accident — the data is filesystem-keyed and
process-invariant, and the same staleness contract carries over
(snapshot-at-first-read, no invalidation).
`WorkingTree::{root,git_dir,branch}` and `prewarm_info` now read/write
those statics directly. The intermediate `PREWARM_INFO_CACHE` snapshot
type is gone — one cache layer instead of two.
Caching spec doc updated to describe both layers (`RepoCache`
per-Repository, plus the process-wide git-discovery statics).
## Bench
`benches/alias.rs`, stub variants, 30s measurement:
| Variant | Before | After | Change |
|---|---|---|---|
| `dispatch/wt_version` | 3.48 ms | 3.54 ms | unchanged (clap exits
before `prewarm`) |
| `dispatch/warm/1` | 22.4 ms | 18.2 ms | **−18.5%** |
| `dispatch/warm/100` | 24.3 ms | 18.2 ms | **−24.1%** |
| `dispatch/cold/1` | 22.6 ms | 19.3 ms | **−17.2%** |
| `dispatch/cold/100` | 28.9 ms | 20.1 ms | **−27.2%** |
All four worktree variants regress to ~18–20 ms median regardless of
cold/warm or worktree count. `wt_version` is unchanged because
`--version` is handled by clap inside `parse_cli` before
`Repository::prewarm()` is called — same code path as before.
## Edge cases
- **Bare repo at the bare root** — `--show-toplevel` errors but
`--git-common-dir` lands first, so we cache the common dir.
`WORKTREE_ROOTS` stays empty for that path (its membership invariant —
`contains_key` ⇔ inside a worktree — must hold), so `prewarm_info`
reforks once. Net cost: same as the unoptimized baseline. The prewarm
doc spells this out.
- **Unborn HEAD** — every selector emits a line but rev-parse exits
non-zero. We populate `WORKTREE_ROOTS` and `GIT_DIRS` but leave
`CURRENT_BRANCHES` to the `symbolic-ref` fallback in
`WorkingTree::branch`, matching the existing `prewarm_info` behaviour.
- **Outside any work tree** (`wt` from a non-repo dir) — merged batch
fails entirely, nothing cached. `Repository::at` later runs its own
rev-parse and surfaces the discovery error normally.
## Test plan
- [x] `cargo test --lib --bins` (1076 + 607 passing, all 4 prewarm tests
pass)
- [x] `pre-commit run --all-files` (fmt + clippy + lychee + custom
checks)
- [x] Trace inspection on cold cache: subprocess #2 absent, both
downstream callers hit cache
- [x] Bench compare on `dispatch/{warm,cold}/{1,100}`
- [x] Manual smoke tests: unborn HEAD repo, bare repo, linked worktree
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
This was referenced May 15, 2026
This was referenced May 25, 2026
max-sixty
added a commit
that referenced
this pull request
May 26, 2026
… on stderr (#2913) ## Motivation The `-v` / `-vv` UX had three small issues that compounded: 1. **`output.log` is misnamed.** It holds the *uncapped raw stdout/stderr of every subprocess `wt` spawns* — multi-MB possible (`git log -p`, patch-id pipelines, etc.). "output" reads as "stuff `wt` printed" — the small thing — when it's actually the big thing. Easy to misread. 2. **`-vv` went fully dark on stderr.** PR #2892 moved the noisy debug pipeline to files at `-vv`; in the process, the stderr layer was disabled entirely. Users running `-vv` to see hook output (info-level, which `-v` shows on stderr) suddenly couldn't. 3. **`-v` help text was a 150-char one-liner** packed into a parenthetical, and the surrounding docs leaned on a "stderr stays readable / `log::*` pipeline" framing that was Rust-jargon-flavored and implied stderr-quiet at `-vv` — which is no longer true after change #2. ## Change - **Rename `output.log` → `subprocess.log`.** Filename now matches content. `OUTPUT` static → `SUBPROCESS`, plus the related `OutputMakeWriter` / `OutputFileFormat` / `build_output_layer` symbol renames. - **`-vv` keeps the Info baseline on stderr.** `build_stderr_layer` no longer returns `None` at `-vv`; debug-level records still route to file layers only, so the terminal stays readable while info-level status (hook output, template variables, the `Tracing to ...` pointer) shows the same as at `-v`. - **`-v` help text rewritten** to describe both levels cleanly without a wall of detail. - **`docs/content/faq.md` gets a "What does -v / -vv do?" section** with a three-level table. - **Docs cleanup**: drop "stderr stays readable" / `log::*` jargon / "but not subprocess.log" negative framing from user-facing prose. ## Notes for review - The only `log::info!` site in the codebase is `commands/picker/mod.rs:389` (a single picker error message), so making `-vv` show info-level on stderr doesn't add meaningful noise. - `test_vv_log_pipeline_silent_on_stderr` is renamed to `test_vv_debug_pipeline_silent_on_stderr` — its assertions only check debug-level records stay out of stderr (they do); the old name implied the whole `log::*` pipeline was silent, which was never quite true (direct `eprintln!` always showed) and is less true now (info-level routes to stderr). - 67 of the 69 changed files are snapshot updates (help text and one diagnostic snapshot) and auto-synced doc/skill mirrors. `git diff --stat -- 'tests/snapshots/*' 'docs/content/*' 'skills/worktrunk/reference/*' | tail -1` separates them. - CHANGELOG: not touched. The historical entry that introduced `output.log` (`#2201`) stays accurate for its release; this rename gets a new line in the next release. ## Tests 3870 tests pass. Re-snapshotted all `test_help_*` snapshots, three `step_alias` snapshots that quote the global help, and the diagnostic file format snapshot. > _This was written by Claude Code on behalf of max-sixty_ Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
worktrunk-bot
added a commit
that referenced
this pull request
Jun 26, 2026
Resolves the conflict in tests/integration_tests/switch_picker.rs. main (#3247) added PreviewNotifier, which auto-repaints a late preview when its background compute lands, and removed the test-side Alt-<digit> keystroke re-issue that #3238 used to paper over stranded "Loading…" placeholders. The two de-flakes in this PR are orthogonal to that: - Flake #1 (alt-x sticky exit code) — a separate region, auto-merged cleanly. - Flake #2 (comments-tab cursor reset) — kept. PreviewNotifier re-runs only the *preview* for the selected row (notify_row_changed); it does not stop on_update's request_render from resetting skim's cursor to the top after an async row decoration lands. So the cursor-confirmed Down is still needed. Resolution keeps the cursor-arrow re-issue (restored wait_for_stable_until's nudge param, now scoped to cursor recovery and renamed PREVIEW_REISSUE_INTERVAL -> CURSOR_REISSUE_INTERVAL) and drops the obsolete Alt-<digit> re-issue branch (is_alt_digit_tab deleted) in favor of main's PreviewNotifier path. Full switch_picker suite passes locally on Linux. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Jun 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR tests several changes merged from main to verify CI stability:
wt switchTest plan
🤖 Generated with Claude Code