Background & motivation
A git worktree only contains tracked files, so ignored files never appear in a new worktree. Under AI-driven workflows this causes two pain points:
- Broken context: AI workflows often generate documents in the repo root (plans, design notes, context files). We usually don't want to commit them, so we ignore them via
.gitignore — but agents working inside a worktree need exactly those documents to keep context consistent.
- Lost output: untracked files an agent newly creates inside a worktree (e.g.
docs/xxx.md) are permanently lost when the task is merged and the worktree is removed.
Today parallel-code works around this with a hardcoded allowlist (SYMLINK_CANDIDATES, only 8 entries such as .env and node_modules) that gets symlinked into each worktree. It cannot cover user-defined ignored files.
Proposal
Make worktree creation and merge behavior configurable per task:
- On task creation: let the user check which ignored files/directories to bring into the worktree (e.g.
.env, docs/), and choose how each entry is brought in:
- Symlink: shared with the main checkout (good for large directories that don't need isolation, like
node_modules);
- Copy: an independent copy inside the worktree (good for documents the agent may modify, like
.env).
- On task merge: optionally carry untracked files newly created inside the worktree (e.g.
docs/xxx.md) back into the project root, so output isn't lost when the worktree is removed.
Relationship to Claude Code's .worktreeinclude
Claude Code's .worktreeinclude solves a similar problem, but it only copies ignored files one way, at creation time; they are deleted together with the worktree on cleanup and never carried back to the main checkout. This proposal extends that idea with:
- a per-entry choice of symlink vs. copy (symlink avoids the copy cost of large directories like
node_modules; copy guarantees isolation);
- carrying untracked files created in the worktree back to the project root on merge, preventing output loss.
Implementation sketch
- Enumeration:
git ls-files --others --ignored --exclude-standard --directory, collapsed to top-level entries of the repo root. A single command covers all ignore mechanisms (.gitignore, nested gitignores, .git/info/exclude, global excludesFile) — no need to parse gitignore syntax ourselves. .worktrees/ and .git must be force-excluded (to avoid linking the worktree directory into itself).
- Creation: symlink or copy each checked entry according to its config.
- Merge: in
mergeTask(), before removeWorktree, copy the entries marked as "carry back" from the worktree to the project root.
- This feature can replace the existing hardcoded
SYMLINK_CANDIDATES allowlist.
Open questions
- Where should the configuration live: a
.worktreeinclude-style file inside the repo (shareable via git, compatible with Claude Code conventions) vs. an in-app per-project setting?
- On carry-back in copy mode, if the same file was also modified in the main checkout, how should conflicts be handled (overwrite / skip with a warning / keep both)?
- Default selection policy (large ignored directories like
dist/ should presumably not be copied by default?)
Background & motivation
A git worktree only contains tracked files, so ignored files never appear in a new worktree. Under AI-driven workflows this causes two pain points:
.gitignore— but agents working inside a worktree need exactly those documents to keep context consistent.docs/xxx.md) are permanently lost when the task is merged and the worktree is removed.Today parallel-code works around this with a hardcoded allowlist (
SYMLINK_CANDIDATES, only 8 entries such as.envandnode_modules) that gets symlinked into each worktree. It cannot cover user-defined ignored files.Proposal
Make worktree creation and merge behavior configurable per task:
.env,docs/), and choose how each entry is brought in:node_modules);.env).docs/xxx.md) back into the project root, so output isn't lost when the worktree is removed.Relationship to Claude Code's
.worktreeincludeClaude Code's
.worktreeincludesolves a similar problem, but it only copies ignored files one way, at creation time; they are deleted together with the worktree on cleanup and never carried back to the main checkout. This proposal extends that idea with:node_modules; copy guarantees isolation);Implementation sketch
git ls-files --others --ignored --exclude-standard --directory, collapsed to top-level entries of the repo root. A single command covers all ignore mechanisms (.gitignore, nested gitignores,.git/info/exclude, global excludesFile) — no need to parse gitignore syntax ourselves..worktrees/and.gitmust be force-excluded (to avoid linking the worktree directory into itself).mergeTask(), beforeremoveWorktree, copy the entries marked as "carry back" from the worktree to the project root.SYMLINK_CANDIDATESallowlist.Open questions
.worktreeinclude-style file inside the repo (shareable via git, compatible with Claude Code conventions) vs. an in-app per-project setting?dist/should presumably not be copied by default?)