Skip to content

feat: add sparse checkout support for workspaces - #93

Open
Ziinc wants to merge 10 commits into
mainfrom
claude/sparse-checkouts-workspace-ark3sj
Open

feat: add sparse checkout support for workspaces#93
Ziinc wants to merge 10 commits into
mainfrom
claude/sparse-checkouts-workspace-ark3sj

Conversation

@Ziinc

@Ziinc Ziinc commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds sparse checkout functionality to workspaces, allowing users to create workspaces that materialize only a subset of files matching specified patterns. This is useful for large monorepos where developers only need to work with specific directories.

Key Changes

Core Functionality

  • Sparse pattern validation and application: Added parse_sparse_patterns() in jj.rs to validate user-supplied patterns and convert them to jj's RepoPathBuf format. Patterns are validated before any side effects occur.
  • Workspace creation with sparse patterns: Extended create_workspace() to accept an optional sparse_patterns parameter that gets registered in jj's working-copy state via set_sparse_patterns().
  • Pattern validation logic: Moved files outside sparse patterns are rejected upfront to prevent commits with invisible files. Empty pattern lists are normalized to None (full checkout).

Database and Metadata

  • Database schema: Added sparse_patterns column to the workspaces table to persist patterns across sessions.
  • Metadata parsing: Created parse_workspace_metadata() function in core/workspaces.rs to centralize metadata JSON parsing, handling sparse_patterns alongside existing title, description, and moved_files fields.
  • Workspace struct: Updated local_db::Workspace to include sparse_patterns field.

Frontend Integration

  • UI components: Added sparse paths input field to WorkspaceLeftPanel and UnifiedWorkspaceDialog.
  • Metadata helpers: Created workspaceMetadata.ts with parseSparsePathsInput() and buildCreateMetadata() utilities to handle newline-separated sparse path input from users.
  • API types: Extended Workspace interface to include optional sparse_patterns field.

CLI and Commands

  • Command dispatch: Updated NAPI dispatch and Tauri command handlers to pass sparse patterns through the metadata JSON.
  • CLI support: Added --sparse flag to the CLI workspace add command.

Testing

  • Comprehensive test suite: Added core_workspaces_sparse_checkout_test.rs with 11 tests covering:
    • Basic sparse materialization
    • Full checkout behavior (None vs empty patterns)
    • Pattern validation and error handling
    • Single-file patterns
    • Moved files validation
    • Included copy files behavior
    • Stacked workspaces with sparse patterns
    • Database persistence
    • Snapshotting behavior (files outside patterns not tracked)
    • jj sparse list registration
  • Integration tests: Added TypeScript integration test for sparse workspace creation.
  • Unit tests: Added tests for metadata parsing utilities.

Implementation Details

  • Validation timing: Sparse patterns are validated in parse_sparse_patterns() before workspace creation, ensuring no partial state is left behind on errors.
  • Pattern matching: Patterns use jj's prefix matching semantics where src matches both the src file and everything under src/.
  • Normalization: Patterns are normalized by stripping ./ prefix and trailing slashes, with duplicates removed.
  • jj integration: Sparse patterns are set on the working copy while it's still empty, ensuring only matching paths are materialized during checkout.
  • Backward compatibility: Existing code paths without sparse patterns continue to work unchanged; None and empty lists both result in full checkouts.
    https://claude.ai/code/session_01ARzJzBaQCPUpHgYJqdi1zF

@Ziinc

Ziinc commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator Author

test

claude added 5 commits July 27, 2026 19:14
Workspaces can now be created with jj sparse working-copy patterns so only
matching path prefixes are materialized on disk. Patterns are validated
before any side effect and applied in a dedicated working-copy mutation
between workspace init and checkout, mirroring 'jj workspace add
--sparse-patterns'. None and an empty list both mean a full checkout.

Adds TDD integration tests for materialization, jj sparse registration,
full-checkout fallback, validation, and single-file patterns.
Adds a sparse_patterns TEXT column (JSON array, NULL for full checkouts)
mirroring the moved_files precedent, decodes it in workspace records, and
pins snapshot behavior: files outside the sparse cone are neither reported
as changes nor swept into commits.
…ehavior

Creating a workspace now fails fast when a moved file falls outside the
sparse cone instead of committing a file that would be invisible on disk.
Tests pin that included_copy_files are copied regardless of patterns and
that stacked workspaces respect sparse patterns.
Extracts the duplicated metadata JSON parsing into a shared
core::parse_workspace_metadata (with unit tests) used by both the Tauri
command and the NAPI dispatch, and passes sparse_patterns through. Also
fixes the NAPI create_workspace call that was missing the
included_copy_files argument. Adds a TS integration test covering sparse
and full creation via the NAPI path, and exposes sparse_patterns on the
frontend Workspace type.
treq add gains a repeatable --sparse/-p flag. The creation dialog gets an
optional sparse-paths textarea (plain creation only); metadata JSON is now
built by a shared tested helper that includes sparse_patterns when set.
@Ziinc Ziinc changed the title Add sparse checkout support for workspaces feat: add sparse checkout support for workspaces Jul 27, 2026
Drives the real Stack dialog to create a workspace with sparse paths and
captures the dialog and resulting workspace, asserting only matching
paths materialize on disk.
@Ziinc
Ziinc force-pushed the claude/sparse-checkouts-workspace-ark3sj branch from d43f8dc to f06f969 Compare July 27, 2026 19:57
@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

📸 App QA screenshots

Re-ran the flow whose spec this PR adds or modifies — 4 captures. Other specs in the library were not run.

⬇️ Download the screenshots

workspace-sparse-checkout
  • workspace-sparse-checkout-01-home-full-file-list.png
    • The home repo view's file browser lists the full repository root: src, docs, and README.md.
  • workspace-sparse-checkout-02-dialog-collapsed.png
    • The workspace creation dialog is open over the dashboard.
    • A collapsed "Advanced" toggle with a right-pointing chevron sits between the Description field and the Branch Name field.
    • No sparse paths textarea is visible.
  • workspace-sparse-checkout-03-advanced-expanded-filled.png
    • The "Advanced" toggle is expanded (downward chevron) revealing the sparse paths textarea.
    • The Branch Name input contains "feat/sparse-demo".
    • The sparse paths textarea contains "src".
  • workspace-sparse-checkout-04-workspace-sparse-file-list.png
    • The workspace header shows the feat/sparse-demo branch, meaning the sparse workspace was created and opened.
    • The workspace's file browser lists only src (plus .jj) — docs and README.md from capture 01 are absent.
    • No error toast or dialog is visible.

Each bullet under a capture is what the spec claims that image should show — open the PNG and check it.


commit 5f552ba · workflow run — this comment is updated in place on each run.

claude added 4 commits July 27, 2026 20:03
hasSourceWorkspace is true even for the home repo (sourceWorkspace is
null, not undefined), which hid the field in the exact flow it targets.
Gate on the actual sourceWorkspace object instead. Caught by the
workspace-sparse-checkout screenshot spec.
The Stack dialog's sparse paths input is an advanced option; hide it in
a collapsible section that defaults to collapsed, following the existing
chevron-toggle pattern. Screenshot spec drives the expand interaction.
Adds a before capture of the home repo's full root file list so the
sparse workspace's reduced file list (only src/) is directly comparable.
The test arrived with the rebase onto main and still called
core::create_workspace with the pre-sparse 6-argument signature,
breaking the rust build on both runners.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants