Conversation
Add a Workspace trait that captures operations commands need, independent of the underlying VCS. GitWorkspace wraps Repository and delegates to existing methods. Nothing consumes the trait yet — this is the foundation for jj support (#926). Co-Authored-By: Claude <noreply@anthropic.com>
Phase 1 of jj workspace support: - VCS detection by filesystem markers (.jj/ vs .git/, co-located prefers jj) - JjWorkspace implementing Workspace trait via jj CLI - Sequential data collection for jj repos (collect_jj) - handle_list dispatches to jj or git path based on detected VCS Git path is completely unchanged — the existing handle_list body is renamed to handle_list_git with identical behavior. Co-Authored-By: Claude <noreply@anthropic.com>
Phase 2 of jj workspace support: - VCS detection at top of handle_switch routes to jj handler - Switch to existing workspace by name - Create new workspace with --create (--base maps to --revision) - Path computation uses same sibling-directory convention as git - No PR/MR resolution (git-only feature) - No hooks (git-only for now) - Git path completely unchanged Co-Authored-By: Claude <noreply@anthropic.com>
Route remove command to jj handler when in a jj repo. Forgets the workspace via `jj workspace forget`, removes the directory, and cd's to default workspace if removing current. Co-Authored-By: Claude <noreply@anthropic.com>
Squash (default): creates new commit on trunk with combined feature changes via `jj squash --from`. No-squash: rebases branch onto trunk. Both modes update the target bookmark and push (best-effort for co-located repos). Handles jj's empty working-copy pattern by detecting the actual feature tip (@- when @ is empty) to avoid referencing abandoned commits. Co-Authored-By: Claude <noreply@anthropic.com>
Extract current_workspace() and trunk_bookmark() to JjWorkspace, and share removal logic between merge and remove handlers via remove_jj_workspace_and_cd(). Co-Authored-By: Claude <noreply@anthropic.com>
28 tests covering list, switch, remove, and merge commands against real jj repositories. Includes JjTestRepo fixture with ANSI-aware change ID filters for deterministic snapshots. Co-Authored-By: Claude <noreply@anthropic.com>
Add `wt step commit/squash/rebase/push` for jj repos with VCS detection routing. Replace all `trunk()` revset usages in shared helpers with the resolved target bookmark name, since `trunk()` only resolves with remote tracking branches. Co-Authored-By: Claude <noreply@anthropic.com>
jj is not installed on CI runners. Gate the jj test module behind `jj-integration-tests` feature flag, matching the existing pattern for `shell-integration-tests`. Co-Authored-By: Claude <noreply@anthropic.com>
The jj integration tests are behind a feature flag, but their snapshot files are always present in the repo. On Linux CI, `--unreferenced reject` catches these as orphaned. Fix by: - Installing jj-cli on Linux CI (where --unreferenced reject runs) - Conditionally adding jj-integration-tests feature when jj is available Co-Authored-By: Claude <noreply@anthropic.com>
RUSTDOCFLAGS='-Dwarnings' treats these as errors. Rust auto-resolves intra-doc links when the link text matches the type name. Co-Authored-By: Claude <noreply@anthropic.com>
Install jj-cli on the code-coverage job and enable the jj-integration-tests feature so jj handler code is covered. Co-Authored-By: Claude <noreply@anthropic.com>
Remove separate jj-integration-tests feature flag. jj tests now run under shell-integration-tests alongside shell/PTY tests, gated with cfg(all(unix, feature = "shell-integration-tests")). Install jj on macOS CI via brew to match Linux CI. Co-Authored-By: Claude <noreply@anthropic.com>
- Clean workspace listing (is_dirty clean path) - Switch without --cd (early return path) - Remove current workspace without name arg - Switch --create with --base revision - List workspace with commits ahead (branch_diff_stats) - Switch --create when path already exists (error path) Co-Authored-By: Claude <noreply@anthropic.com>
Exercises all Workspace trait methods on a real git repository, covering the Workspace for GitWorkspace implementation and Repository::create_worktree. These thin wrappers had no direct callers yet (git paths still use Repository directly). Co-Authored-By: Claude <noreply@anthropic.com>
Two targeted tests for coverage gaps: - test_jj_list_json: exercises the JSON output path in handle_list_jj - test_jj_remove_already_deleted_directory: exercises the warning path when workspace directory was deleted externally Co-Authored-By: Claude <noreply@anthropic.com>
Add src/workspace/git.rs to no-direct-cmd-output exclude list (test fixtures use Command::output() directly). Fix rustfmt formatting in jj integration test. Co-Authored-By: Claude <noreply@anthropic.com>
Covers the new jj commit prompt builder function in the llm module. Co-Authored-By: Claude <noreply@anthropic.com>
Directly calls kind(), has_staging_area(), default_branch_name(), is_dirty() (both clean and dirty paths), and branch_diff_stats() on JjWorkspace to cover ~28 lines that aren't reached by normal wt command flows but are required by the Workspace trait. Co-Authored-By: Claude <noreply@anthropic.com>
Expand the Workspace trait to be the primary VCS-agnostic interface, replacing scattered detect_vcs() calls and the GitWorkspace wrapper. Phase 1: Move LineDiff, IntegrationReason, path_dir_name to workspace::types Phase 2: Add identity, commit, push methods to Workspace trait Phase 3: Remove GitWorkspace wrapper, implement Workspace for Repository directly Phase 4: Make CommandEnv hold Box<dyn Workspace> instead of Repository Phase 5: Consolidate VCS routing into command modules (merge, step, remove) Phase 6: Update jj handlers to use trait methods Additional improvements: - require_repo() returns Result instead of panicking - require_git() guard gives clear errors for jj users on git-only commands - handle_merge_jj respects user config defaults for squash/remove - JjWorkspace::project_identifier uses git remote URL when available - current_workspace_path() trait method eliminates downcast in CommandEnv Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Owner
Author
|
(working on improving this, needs lots of work) |
Add advance_and_push and squash_commits as Workspace trait methods, making step push fully trait-based with zero VcsKind branching. Git: fast-forward check via is_ancestor, stash/restore target worktree, local push. Jj: is_rebased_onto guard, bookmark set, jj git push. Squash: Git uses reset --soft + commit, Jj uses new + squash --from + bookmark set. Both jj handlers (step squash, merge) now use trait methods instead of standalone functions. Deleted: handle_push_jj, squash_into_trunk, push_bookmark. Extracted: collect_squash_message helper for jj commit message assembly. Co-Authored-By: Claude <noreply@anthropic.com>
advance_and_push now returns PushResult (commit count + stats summary) instead of bare usize. Git impl emits progress message, commit graph, and diffstat to stderr during the push operation, preserving the exact output ordering (stash → graph → restore → success). Command handler formats the final success message with stats parenthetical. Co-Authored-By: Claude <noreply@anthropic.com>
Replace &Repository with &dyn Workspace throughout the hook pipeline, enabling hooks in jj repositories: - expand_template: take worktree_map instead of &Repository - spawn_detached: take log_dir: &Path instead of &Repository - CommandContext: workspace field replaces repo field, with repo() downcast for git-specific operations - CommandEnv::context() returns CommandContext directly (infallible) - Workspace trait: add load_project_config, wt_logs_dir, switch_previous, set_switch_previous - handle_switch_jj: full rewrite with hooks, --execute, switch-previous, shell integration - Extract shared expand_and_execute_command for --execute handling Co-Authored-By: Claude <noreply@anthropic.com>
Remove require_git() guards from all hook commands (run_hook, add_approvals, clear_approvals, handle_hook_show) and replace Repository-specific calls with Workspace trait equivalents. The hook infrastructure was already generalized in prior commits — this removes the last barrier preventing hooks from running in jj repos. Also adds VCS-neutral messaging guidance to the user output skill: don't mention specific backends unless the context is already VCS-specific. Co-Authored-By: Claude <noreply@anthropic.com>
Env var rename (WT_TEST_* → WORKTRUNK_TEST_*), shell integration hint addition, and jj push behavior changes from main. Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # .github/workflows/ci.yaml
…ring> Both implementations (git, jj) are infallible — the Result wrapper added no value and forced callers to .ok().flatten() unnecessarily. Co-Authored-By: Claude <noreply@anthropic.com>
Clarify that Worktrunk supports git and jj, with guidance on keeping the Workspace trait signatures simple and tied to actual implementation requirements rather than hypothetical backends.
The jj push output includes git commit hashes (hex, e.g., "26009b197b6c")
which vary between runs. The existing snapshot filters only matched
pure-alpha jj change IDs ([a-z]{12}), missing hex hashes with digits.
Add a [0-9a-f]{12} filter after the alpha-only filters so change IDs
are still caught first, and hex commit hashes are redacted as
[COMMIT_HASH].
Co-Authored-By: Claude <noreply@anthropic.com>
Replace the global BASE_PATH mechanism with std::env::set_current_dir(). This simplifies path handling by leveraging the OS-level current working directory instead of maintaining a separate base path variable. The -C flag now changes the actual working directory, which affects all code (git, jj, etc.) that uses relative paths or current_dir(). Remove set_base_path() export and related static initialization.
Merge VCS-specific squash implementations into a single `do_squash()` function in `step_commands.rs`. This eliminates code duplication and enables both git and jj to share message generation, LLM prompting, and outcome handling. Changes: - Extract `do_squash()` core: count commits, generate message, execute squash - Add `Workspace` trait methods for VCS-agnostic diff/prompt data: `feature_head()`, `diff_for_prompt()`, `recent_subjects()` - Change `squash_commits()` return type from `String` to `SquashOutcome` enum (handles both success and "no net changes" cases) - Remove jj-specific `handle_squash_jj()` and `collect_squash_message()` - Update `handle_merge_jj()` to call shared `do_squash()` instead - Enable `--show-prompt` for jj (now trait-based, not git-only) - Update `remove_jj_workspace_and_cd()` signature to include hook control flags
Consolidate workspace detection and VCS routing into `open_workspace()`, eliminating the pattern of calling both `detect_vcs()` and `Repository::current()` separately. Commands now open the workspace once and downcast to `Repository` when git-specific features are needed. This reduces boilerplate across command handlers while improving error consistency. `CommandEnv` methods now accept pre-opened workspaces, and `require_git_workspace()` replaces the old two-step `require_git()` + `Repository::current()` pattern.
…tests jj config get doesn't accept --repo (unlike config set). This caused switch_previous() to silently fail on jj 0.38+, making `wt switch -` always error with "No previous workspace to switch to" in jj repos. Also adds 5 integration tests for uncovered jj code paths: - switch-previous, merge no-net-changes, merge no-squash, merge zero-commits-ahead, switch-to-current-workspace Co-authored-by: Claude <noreply@anthropic.com>
- Merge at-trunk with removal (NoCommitsAhead + workspace removal) - Merge no-net-changes with removal (NoNetChanges + workspace removal) - Switch records previous workspace for `wt switch -` Co-authored-by: Claude <noreply@anthropic.com>
Extend workspace/git.rs unit test to exercise commit(), switch_previous(), set_switch_previous(), and advance_and_push() through the Workspace trait interface. Add jj integration tests for merge with implicit target (trunk_bookmark resolution) and step commit with empty description (fallback message generation). Extend jj workspace trait test with feature_tip, commit, commit_subjects, resolve_integration_target, wt_logs_dir, set_switch_previous(None), and is_rebased_onto. Co-Authored-By: Claude <noreply@anthropic.com>
Add 4 new jj integration tests: - switch --create with hooks (post-create, post-switch, post-start) - switch existing with hooks (post-switch) - switch --create with --execute - switch existing with --execute Fix CI test failure: add repo-local git user.name/email config for test_workspace_trait_on_real_repo (CI runners lack global config). Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Each command handler now calls open_workspace() once at the top, then uses downcast_ref::<Repository>() to route git vs jj paths. This eliminates scattered detect_vcs() calls and redundant Repository::current() calls across 9+ command entry points. Key changes: - Add CommandEnv::with_workspace() constructors that accept pre-opened workspace - Replace require_git() with require_git_workspace() (downcast-based) - Move project_id resolution from main.rs into list/select handlers - Simplify main.rs by passing raw CLI flags to handlers - Fix jj step push panic: add .context() for multiline errors Co-Authored-By: Claude <noreply@anthropic.com>
Part 1: Replace parallel build_commit_prompt/build_jj_commit_prompt and generate_commit_message paths with single VCS-agnostic functions. Add CommitInput struct and committable_diff_for_prompt trait method. Unify --show-prompt to work for both git and jj. Part 2: Add hook approval and execution (pre-merge, post-merge) to jj merge handler, bringing it to feature parity with git merge. Part 3: Add PostSwitch hook execution when removing the current jj workspace, fixing gap where it was approved but never executed. Co-authored-by: Claude <noreply@anthropic.com>
Add coverage for 15+ previously untested Workspace trait methods in the git implementation: root_path, current_workspace_path, current_name, project_identifier, feature_head, recent_subjects, load_project_config, wt_logs_dir, resolve_integration_target, is_rebased_onto, diff_for_prompt, committable_diff_for_prompt, and both rebase_onto code paths (fast-forward and diverged). Adds git_at helper for linked worktree git commands. Co-Authored-By: Claude <noreply@anthropic.com>
Replace git-only require_git_workspace in config create --project with VCS-agnostic workspace.current_workspace_path(). Implement JjWorkspace::recent_subjects() via jj log so LLM commit messages include recent commit style context, matching git behavior. Co-Authored-By: Claude <noreply@anthropic.com>
Consolidate jj removal logic into remove_command.rs, eliminating handle_remove_jj as a public entry point. Extract approve_remove_hooks as a shared helper used by both VCS backends. Update test snapshots to reflect streamed git output during worktree creation.
Add two more test scenarios to test_workspace_trait_on_real_repo: - advance_and_push with dirty target worktree: exercises the stash_target_if_dirty → push → restore_stash path - rebase_onto with conflicting changes: exercises the RebaseConflict error path when both branches modify the same file Also derive Debug on RebaseOutcome (required by unwrap_err in test). Co-Authored-By: Claude <noreply@anthropic.com>
… coverage - IntegrationReason::symbol() and description() - LineDiff::is_empty() and From conversions - path_dir_name() - ProjectConfig::ci_platform(), load_from_root() (valid, invalid TOML, unreadable) - ProjectListConfig::is_configured() - CommandContext Debug format - build_worktree_map() via git workspace test - Simplify test assertion format strings to reduce uncovered lines Co-Authored-By: Claude <noreply@anthropic.com>
…ace_path fallback - Fix CI: add command_executor.rs to no-direct-cmd-output exclude list (test fixtures use std::process::Command for git init, matching existing exclusions for config/test.rs and workspace/git.rs) - Add 7 unit tests for CommandContext and build_hook_context covering: repo() downcast, branch_or_head(), project_id(), commit_generation(), hook context variable expansion, detached HEAD, and git-specific fields - Add workspace_path directory-name fallback test (exercises lines 63-65) - Add feature_head trait dispatch test Co-Authored-By: Claude <noreply@anthropic.com>
Add tests for `prepare_commands()` / `expand_commands()` covering single, named, template-var, and extra-var cases. Add tests for all 5 match arms of the `generate_commit_message` fallback path (0, 1, 2, 3, 4+ files). Simplify `init_test_repo()` to avoid uncoverable assert format-arg lines. Co-Authored-By: Claude <noreply@anthropic.com>
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
Workspacetrait so commands can dispatch to git or jj handlerslist,switch,remove,merge, andstep(commit/squash/rebase/push)Part of #926
Test plan
cargo test)pre-commit run --all-files)handle_step_jj.rs