Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ git branch -d feat</code></pre></td>
- **[LLM commit messages](https://worktrunk.dev/llm-commits/)** — generate commit messages from diffs
- **[Merge workflow](https://worktrunk.dev/merge/)** — squash, rebase, merge, clean up in one command
- **[Interactive picker](https://worktrunk.dev/switch/#interactive-picker)** — browse worktrees with live diff and log previews
- **[Copy build caches](https://worktrunk.dev/step/#wt-step-copy-ignored)** — skip cold starts by sharing `target/`, `node_modules/`, etc between worktrees
- **[Share build caches](https://worktrunk.dev/step/#wt-step-copy-ignored)** — ten worktrees get `target/`, `node_modules/`, etc without building or copying them (on APFS, btrfs, and XFS)
- **[`wt list --full`](https://worktrunk.dev/list/#full-mode)** — [CI status](https://worktrunk.dev/list/#ci-status) and [AI-generated summaries](https://worktrunk.dev/list/#llm-summaries) per branch
- **[PR checkout](https://worktrunk.dev/switch/#pull-requests-and-merge-requests)** — `wt switch pr:123` to jump straight to a PR's branch
- **[Dev server per worktree](https://worktrunk.dev/tips-patterns/#dev-server-per-worktree)** — `hash_port` template filter gives each worktree a unique port
Expand Down
6 changes: 6 additions & 0 deletions docs/src/content/docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ These tools can be used together—run git-machete or git-town inside individual

Git TUIs operate on a single repository. Worktrunk manages multiple worktrees, runs automation hooks, and aggregates status across branches. TUIs work inside each worktree directory.

## How much disk do worktrees use?

Worktrees share one `.git`. Each adds a checkout of the tracked files, plus whatever gitignored build output you copy in.

On APFS, btrfs, and XFS (not ext4 or NTFS), [`wt step copy-ignored`](/step/#copy-on-write) reflinks that output, so a new worktree shares the primary worktree's disk blocks. A later build rewrites only what changed, and the rest stays shared. On one machine, 56 worktrees of a Rust repository with a 40GB `target/` came to 2.6TB by `du` and 0.7TB on disk.

## Does Worktrunk support stacked branches?

Not natively — stacked-branch workflows are a large design space, so Worktrunk treats them as an extension rather than a built-in. [`worktrunk-sync`](https://github.com/pablospe/worktrunk-sync) is a community tool that auto-detects the branch dependency tree from git history and rebases each branch onto its parent in topological order. Install with `cargo install worktrunk-sync` and run as `wt sync` (via [custom subcommands](/extending/#custom-subcommands)).
Expand Down
17 changes: 9 additions & 8 deletions docs/src/content/docs/step.md
Original file line number Diff line number Diff line change
Expand Up @@ -611,16 +611,18 @@ Without `.worktreeinclude`, the command is a no-op (it reports that nothing was
| Generated assets | Images, ML models, binaries too large for git |
| Environment files | `.env` (if not generated per-worktree) |

### Performance
### Copy-on-write

Reflink copies share disk blocks until modified — no data is actually copied. For a 14GB `target/` directory:
Files are reflinked where the filesystem supports it: APFS (macOS), btrfs and XFS (Linux), ReFS (Windows). A reflinked copy shares the source's disk blocks until one side writes. For a 14GB `target/` directory:

| Command | Time |
|---------|------|
| `cp -R` (full copy) | 2m |
| `cp -Rc` / `wt step copy-ignored` | 20s |
| Command | Time | Disk |
|---------|------|------|
| `cp -R` (full copy) | 2m | 14GB |
| `cp -Rc` / `wt step copy-ignored` | 20s | ~0 |

Uses per-file reflink (like `cp -Rc`) — copy time scales with file count.
On ext4 and NTFS, which have no reflink, every file is copied in full.

Reflinks are per file (like `cp -Rc`), so copy time scales with file count.

Use the `post-start` hook so the copy runs in the background. Use `pre-start` instead if subsequent hooks or `--execute` command need the copied files immediately.

Expand Down Expand Up @@ -654,7 +656,6 @@ Virtual environments contain absolute paths and can't be copied. Use `uv sync` i
The `.worktreeinclude` pattern is shared with [Claude Code on desktop](https://code.claude.com/docs/en/desktop), which copies matching files when creating worktrees. Differences:

- worktrunk copies all gitignored files by default; Claude Code requires `.worktreeinclude`. Pass `--require-include` to match Claude Code (copy nothing without `.worktreeinclude`)
- worktrunk uses copy-on-write for large directories like `target/` (see Performance above)
- worktrunk runs as a configurable hook in the worktree lifecycle

### Command reference
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/worktrunk.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ git branch -d feat</code></pre></td>
- **[LLM commit messages](/llm-commits/)** — generate commit messages from diffs
- **[Merge workflow](/merge/)** — squash, rebase, merge, clean up in one command
- **[Interactive picker](/switch/#interactive-picker)** — browse worktrees with live diff and log previews
- **[Copy build caches](/step/#wt-step-copy-ignored)** — skip cold starts by sharing `target/`, `node_modules/`, etc between worktrees
- **[Share build caches](/step/#wt-step-copy-ignored)** — ten worktrees get `target/`, `node_modules/`, etc without building or copying them (on APFS, btrfs, and XFS)
- **[`wt list --full`](/list/#full-mode)** — [CI status](/list/#ci-status) and [AI-generated summaries](/list/#llm-summaries) per branch
- **[PR checkout](/switch/#pull-requests-and-merge-requests)** — `wt switch pr:123` to jump straight to a PR's branch
- **[Dev server per worktree](/tips-patterns/#dev-server-per-worktree)** — `hash_port` template filter gives each worktree a unique port
Expand Down
2 changes: 1 addition & 1 deletion plugins/worktrunk/skills/worktrunk/reference/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions plugins/worktrunk/skills/worktrunk/reference/faq.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions plugins/worktrunk/skills/worktrunk/reference/step.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/worktrunk/skills/worktrunk/reference/worktrunk.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions skills/worktrunk/reference/faq.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions skills/worktrunk/reference/step.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion skills/worktrunk/reference/worktrunk.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions src/cli/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,16 +379,18 @@ Without `.worktreeinclude`, the command is a no-op (it reports that nothing was
| Generated assets | Images, ML models, binaries too large for git |
| Environment files | `.env` (if not generated per-worktree) |

## Performance
## Copy-on-write

Reflink copies share disk blocks until modified — no data is actually copied. For a 14GB `target/` directory:
Files are reflinked where the filesystem supports it: APFS (macOS), btrfs and XFS (Linux), ReFS (Windows). A reflinked copy shares the source's disk blocks until one side writes. For a 14GB `target/` directory:

| Command | Time |
|---------|------|
| `cp -R` (full copy) | 2m |
| `cp -Rc` / `wt step copy-ignored` | 20s |
| Command | Time | Disk |
|---------|------|------|
| `cp -R` (full copy) | 2m | 14GB |
| `cp -Rc` / `wt step copy-ignored` | 20s | ~0 |

Uses per-file reflink (like `cp -Rc`) — copy time scales with file count.
On ext4 and NTFS, which have no reflink, every file is copied in full.

Reflinks are per file (like `cp -Rc`), so copy time scales with file count.

Use the `post-start` hook so the copy runs in the background. Use `pre-start` instead if subsequent hooks or `--execute` command need the copied files immediately.

Expand Down Expand Up @@ -422,7 +424,6 @@ Virtual environments contain absolute paths and can't be copied. Use `uv sync` i
The `.worktreeinclude` pattern is shared with [Claude Code on desktop](https://code.claude.com/docs/en/desktop), which copies matching files when creating worktrees. Differences:

- worktrunk copies all gitignored files by default; Claude Code requires `.worktreeinclude`. Pass `--require-include` to match Claude Code (copy nothing without `.worktreeinclude`)
- worktrunk uses copy-on-write for large directories like `target/` (see Performance above)
- worktrunk runs as a configurable hook in the worktree lifecycle
"#)]
CopyIgnored {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,18 @@ Without .worktreeinclude, the command is a no-op (it reports that nothin
Generated assets Images, ML models, binaries too large for git
Environment files .env (if not generated per-worktree)

Performance
Copy-on-write

Reflink copies share disk blocks until modified — no data is actually copied. For a 14GB target/ directory:
Files are reflinked where the filesystem supports it: APFS (macOS), btrfs and XFS (Linux), ReFS (Windows). A reflinked copy shares the source's disk blocks until one side writes. For a 14GB target/ directory:

Command Time
───────────────────────────── ────
cp -R (full copy) 2m
cp -Rc / wt step copy-ignored 20s
Command Time Disk
───────────────────────────── ──── ────
cp -R (full copy) 2m 14GB
cp -Rc / wt step copy-ignored 20s ~0

Uses per-file reflink (like cp -Rc) — copy time scales with file count.
On ext4 and NTFS, which have no reflink, every file is copied in full.

Reflinks are per file (like cp -Rc), so copy time scales with file count.

Use the post-start hook so the copy runs in the background. Use pre-start instead if subsequent hooks or --execute command need the copied files immediately.

Expand Down Expand Up @@ -186,7 +188,6 @@ Virtual environments contain absolute paths and can't be copied. Use uv sync
The .worktreeinclude pattern is shared with Claude Code on desktop, which copies matching files when creating worktrees. Differences:

- worktrunk copies all gitignored files by default; Claude Code requires .worktreeinclude. Pass --require-include to match Claude Code (copy nothing without .worktreeinclude)
- worktrunk uses copy-on-write for large directories like target/ (see Performance above)
- worktrunk runs as a configurable hook in the worktree lifecycle

----- stderr -----
Loading