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>
|
(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>
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>
Extract list_ignored_entries into Workspace trait and implement for both git and jj backends. Git implementation uses git ls-files directly; jj uses git ls-files with explicit --git-dir pointing to the git backend. Refactor step_copy_ignored to work with workspace abstraction instead of git Repository, enabling support for jj while maintaining git compatibility. Add jj integration tests covering basic copy, --from flag, and --dry-run cases.
For material changes, add a blank line then a body paragraph explaining the change Commands now use the workspace trait instead of directly depending on git. This enables support for multiple VCS backends (git and jj) while maintaining backward compatibility. Git-specific state (markers, CI cache, hints) is now conditionally available through downcasting. Log management and branch tracking work across all supported workspace types.
| "Branch not found" | ||
| "Uncommitted changes" |
There was a problem hiding this comment.
Neither of these really apply to jj, tho.
You are always on a branch, but not a named branch. And the working copy is always committed, there's never uncommitted files (that aren't gitignored).
Under the hood, what jj commit does is a combination of jj describe to update the working copy commit's description, and then jj new, to make a new child commit, and then make that the working copy. It's sugar to be familiar to git users, but it's not necessary to actually commit anything.
# Conflicts: # src/main.rs
The merge from main removed trailing colons from hook status messages. Update the jj_switch_create_with_hooks snapshot to match. Co-Authored-By: Claude <noreply@anthropic.com>
2c5f433 to
46ffab6
Compare
# Conflicts: # src/commands/handle_merge_jj.rs # src/commands/merge.rs # src/commands/mod.rs # src/commands/repository_ext.rs # src/commands/select/mod.rs # src/commands/step_commands.rs # src/workspace/git.rs # src/workspace/jj.rs # src/workspace/mod.rs # src/workspace/types.rs # tests/integration_tests/jj.rs # tests/snapshots/integration__integration_tests__jj__jj_merge_implicit_target.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_no_remove.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_squash.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_squash_with_directive_file.snap # tests/snapshots/integration__integration_tests__jj__jj_step_push_no_remote.snap # tests/snapshots/integration__integration_tests__jj__jj_step_squash_already_integrated.snap
Scope branch diff stats to sparse checkout cone, fix skim cleanup bug, rename advance_and_push to local_push, and update CI dependencies.
Replace the git-specific collect_merge_commands + approve_command_batch pattern with the standard approve_hooks helper that jj merge already uses. Both VCS paths now follow the same "Approve at the Gate" pattern. Co-Authored-By: Claude <noreply@anthropic.com>
When removing a jj workspace after merge, compute and display the integration reason (e.g., "ancestor of main") in the success message, matching git's removal output style. Pass integration info through the removal flow so both `wt merge` and `wt remove` can show how the workspace was integrated into its target.
Add `prepare_commit(path, mode)` to the Workspace trait, replacing duplicated staging logic (warn about untracked files + git add) across commit.rs and step_commands.rs with a single trait method call. - Git: warns about untracked files when StageMode::All, runs git add - Jj: no-op (jj auto-snapshots the working copy) - Remove dead `warn_about_untracked` field from CommitOptions - Remove `warn_if_auto_staging_untracked` from RepositoryCliExt Co-Authored-By: Claude <noreply@anthropic.com>
Move marker, hint, and switch-previous operations from Repository git-config methods to the Workspace trait. This enables jj support while maintaining git compatibility. Key changes: - Add trait methods: branch_marker, set_branch_marker, clear_branch_marker, list_all_markers, clear_all_markers, has_shown_hint, mark_hint_shown, clear_hint, list_shown_hints, clear_all_hints, clear_switch_previous - Implement trait methods for both Repository (git) and JjWorkspace - Update state.rs handlers to use workspace trait methods instead of git-config downcasts - Move hints handling from Repository to trait (git config → both VCS) - Simplify command handlers by removing require_git_workspace calls for marker/hint operations - Update for_each.rs and select.rs to work with generic Workspace
|
Two commits from this branch were accidentally pushed directly to main:
These have been reverted on main in
|
Merges main (which reverted jj support) using ours strategy to preserve the jj code on this branch, then cherry-picks non-revert commits from main. Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # src/commands/commit.rs # src/commands/handle_merge_jj.rs # src/commands/handle_remove_jj.rs # src/commands/merge.rs # src/commands/remove_command.rs # src/commands/repository_ext.rs # src/commands/step_commands.rs # src/workspace/git.rs # src/workspace/jj.rs # src/workspace/mod.rs # tests/snapshots/integration__integration_tests__jj__jj_merge_implicit_target.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_multi_commit.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_no_net_changes.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_no_net_changes_with_remove.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_squash.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_squash_with_directive_file.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_with_no_squash.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_workspace_with_no_user_commits.snap # tests/snapshots/integration__integration_tests__jj__jj_merge_zero_commits_ahead_with_remove.snap
# Conflicts: # src/commands/config/hints.rs # src/commands/config/state.rs # src/commands/for_each.rs # src/commands/list/mod.rs # src/commands/select/mod.rs # src/commands/step_commands.rs # tests/integration_tests/jj.rs
Resolve conflicts between jj workspace generalization and typed TemplateExpandError from main. Keep workspace abstraction (worktree_map), adopt simplified error propagation (plain ? instead of .map_err). Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Documents the planned approach for eliminating ~16 downcast sites via a Box<dyn VcsOps + '_> trait on Workspace. Records current progress (prepare_commit unified) and next steps (introduce VcsOps trait, add guarded_push for merge stash-push-restore pattern). Co-Authored-By: Claude <noreply@anthropic.com>
Bring in 926's merge-main and cargo-fmt commits. Fix type mismatches from TemplateExpandError (expand_template now returns structured error instead of String): add .map_err in format_path and resolve callsites. Co-Authored-By: Claude <noreply@anthropic.com>
Update snapshot tests and assertion for the new TemplateExpandError type from #1041. Error messages now use "Failed to expand {name}:" format instead of "Failed to expand command template". Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # src/commands/list/mod.rs # src/commands/select/mod.rs # src/main.rs
Co-Authored-By: Claude <noreply@anthropic.com>
Resolve conflicts between workspace abstraction (926) and Approvals refactoring (main). Key decisions: - Keep workspace-based API (ctx.workspace instead of ctx.repo) - Apply Approvals separation (Approvals::load() instead of via config) - Apply shell_escape::escape over shlex::try_quote - Apply SwitchSuggestionCtx for --execute error hints - Fix handle_list to not pass config (collect no longer needs it) - Fix select/mod.rs auto-merge issues (duplicate config resolution, repo scoping for summary generation) Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # src/commands/config/show.rs
The commit generation setup prompt appeared in PTY tests when claude was installed on the host, causing snapshot mismatches. Add WORKTRUNK_NO_PROMPTS to the test environment and check it in prompt_commit_generation(). Co-Authored-By: Claude <noreply@anthropic.com>
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