Zewnętrzne worktree
Wykrywanie, przygotowanie i tworzenie w aplikacji.
Technical reference synchronized with Yard’s source. File names and development commands refer to the native app repository.
Discovery
The inspector discovers external Git worktrees when the selected parent site's refresh revision changes,
and offers Refresh Worktrees. The work runs outside the main actor. Three Git commands have a two-second
limit each, optional Git locks are disabled, and worktree list --porcelain -z preserves spaces and embedded
newlines in paths. Discovery accepts at most 512 worktrees / 2 MB of porcelain metadata and bounded administrative
pointer files. Detached and missing worktrees remain distinguishable; missing directories cannot be prepared.
Git pruning removes a stale discovery entry without removing any Yard registration or user directory.
A discovered entry is Not Prepared. Reading discovery never copies .env or dependencies, creates databases,
runs hooks, registers a site/certificate, merges or deploys. Application access does not enable automatic lazy
subdomain preparation. The manual refresh remains available when Git reports a failure.
Identity hashes the canonical common Git directory and the administrative worktree directory name. This survives
branch renames, detached HEAD changes and git worktree move within that repository. The proposed hostname uses
the stable administrative name and an identity suffix, with deterministic longer suffixes for occupied names.
Already prepared workspaces retain their recorded name/domain. Moving the entire common repository changes its
identity; path matching reconciles existing registrations when possible. Unreadable administrative metadata uses
a path-based fallback, so an unavailable identity cannot promise stability across moves.
Explicit preparation
The native inspector exposes Create, Prepare, Relink, Open Preview and Manage. The review sheet
shows the proposed domain, PHP/Node, database mode and concrete effects before the action is enabled. Creation and
preparation produce a shared WorkspacePreparationPlan; the receipt fingerprints the source commit, environment,
Yard/YAML settings and selected dependency lockfiles. Changed inputs reject the old receipt. An already completed
identical registration is idempotent. The sheet has Return / Escape actions, inline progress, visible errors and
YardUI cards, typography and spacing.
External defaults preserve an existing .env byte for byte, existing dependencies, custom files and .nvmrc.
The selected Copy parent .env only when missing option creates a missing environment; a shared SQLite connection
is pinned to the original parent's absolute file rather than accidentally sharing a different relative path.
Dependency reuse copies only missing directories with an identical lockfile. Hooks, migrations and HTTPS are
explicit choices in the native sheet. Existing external YAML copy/env instructions do not overwrite its files.
A separately selected database may update database/isolation keys and invalidate Laravel's cached configuration;
the review explains that change. Remote SQL servers are refused for database creation; retaining an existing
connection remains possible. No secret values enter the plan, errors or preparation progress.
Managed creation keeps the original project intact and uses the same preparation transaction on its new copy.
The CLI's existing YAML hook/migration defaults remain supported; native choices are explicit. Repositories with
linked/separate .git pointer files or a core.worktree override cannot be blindly copied: use a main repository
with its own .git directory, or prepare an external worktree. A failed new copy is removed, with a visible warning
if filesystem cleanup itself fails.
Database and cleanup ownership
Shared, copied and empty database modes remain available. New SQLite databases use identity-specific filenames,
consistent SQLite online backup, exclusive allocation, and reject existing database/sidecar paths. New local SQL
databases use exclusive creation and refuse collisions. PostgreSQL cloning does not terminate source clients.
Only a newly created database receives databaseOwned and a connection-origin fingerprint; old records without
ownership are retained during cleanup. Existing source databases are never dropped as a preparation step.
A process/file lease serializes workspace mutations. The transaction checks project containment and refuses symlink replacement, retains original bytes for overwritten files and Laravel cache removal, and rolls back its new files, site entry, registry row, new certificates and owned database after a failure. Concurrent edits to written files are retained for review. Selected user hooks may modify existing files; those script changes cannot be reversed safely and are explicitly described before execution. Newly created directories are removed only when empty during rollback, preserving independently added files.
External Unlink always keeps the Git worktree directory, branch, environment and dependencies, even if a legacy CLI/API caller requests file deletion. It does not run before-delete hooks. A separately owned database is retained by default in the native UI and removed only when explicitly selected. Registry removal checks that the current site still points at this workspace, preserving an unrelated replacement site. Certificates are removed only with recorded ownership.
Managed deletion can remove only a copy inside Yard's workspace storage. It refuses uncommitted changes and
preserves commits in the parent repository without force-overwriting an existing branch; a conflicting name gets
a yard-preserved/<workspace>-<commit> branch. A SQLite database inside a copy cannot be retained while deleting
its containing directory: keep the files too or export it first. Merge requires clean workspace and parent,
checks the recorded base branch, refuses detached HEAD, aborts only its own failed merge, and pushes only when
explicitly requested. Opening any preview performs none of these operations.
API and persistence
GET /api/workspaces/worktrees?site=…retains an array response and adds stable identity, proposed names, detached/missing/locked and managed/relink metadata. It performs bounded discovery off the main actor.POST /api/workspaces/planaccepts the existing creation fields and an optionalworktreepath and returns a read-only review plan. Both review and preparation verify that the path belongs to the selected repository.POST /api/workspacesadditionally acceptscopy_environment,reuse_dependencies,run_hooksandexpected_revision. Invalid database modes are rejected. CLI callers continue using the shared manager.- Workspace JSON adds optional discovery/ownership fields, decodes historical records, preserves unknown row keys, and refuses corrupt registries instead of replacing them with empty data. Ambiguous short-name lookup no longer silently selects another project's workspace; use its full site name.
Verification
WorktreeManagementTests uses actual temporary Git repositories and SQLite, with injected configuration generation
that never reloads the installed nginx/helper. Cases cover read-only discovery (including newline paths, detached
HEAD and colliding names), identity across move/rename, missing/pruned metadata, unavailable Git/size limits,
external byte preservation, reviewed-input staleness, missing environment choices, real database copy isolation,
partial-failure rollback, external unlink versus managed deletion, branch preservation, merge conflicts,
symlinks/sidecar collisions and future/corrupt persisted fields.
SQLiteNativeUIRegressionTests.testHD007InspectorDiscoversExternalWorktreeWithoutPreparingIt hosts the real
inspector controls and asserts the unprepared entry/domain plus unchanged environment and absent registration.
testHD008ReviewShowsPreservationRuntimeAndExplicitDatabaseChoicesWithoutWrites hosts the actual preparation
sheet, inspects its accessible controls/review and verifies no mutation. The API membership test rejects a
parent checkout passed as an external worktree and rejects invalid database modes. The Escape test presents a
real SwiftUI sheet, sends its window an Escape key event, and verifies dismissal with unchanged files.
YARD_UI_PROJECT_FIXTURES=1 swift test --filter ProjectFeatureVisualTests.testWorkspacesAppearance captures narrow
340/440-point inspector sections and create/prepare/manage sheets in light/dark to /tmp/yard-workspaces-ui.
The fixtures use temporary YARD_HOME, isolated repositories, no models, no services, no TLS setup and no live
application. Final focused run passed 15 backend + 4 native/API/keyboard + 1 visual test, zero failures;
the two pre-existing workspace lifecycle cases also passed in the preceding run. Logs:
/tmp/yard-worktree-final-tests.log and /tmp/yard-worktree-tests.log. All ten final images were inspected;
review text is visible before the preparation options, long explanatory text wraps, and management keeps its
footer available while scrolling. Local SQL daemon creation and certificate-trust flows are not exercised by
these isolated tests.