11 · Git and parallel worktrees
This page is for developers
If you do not write code and your workspaces contain no Git repositories, skip it — the relevant controls stay greyed out.
When a workspace contains a Git repository, operations that would normally need a terminal or IDE can happen inside WorkBuddy. Two capabilities:
- Branches become explicit — see the checked-out branch when creating a task, and switch safely
- Parallel tasks stop interfering — several tasks run in mutually isolated working directories, fully separated at the filesystem level
Both are built on native Git semantics — no extra concepts, so anyone who knows Git can reason directly about what the system does.
1. Branch display and switching
Choosing a branch when creating a task
With a Git repository in the workspace, the new-task page shows the current branch and lets you switch:
- Current branch — the checked-out local branch
- Switch — click the selector for other local or remote branches, with search
- Confirmation — after switching, sending the initial instruction raises a confirmation dialog; without a switch, no confirmation is needed
Selector states:
| Workspace type | Branch selector |
|---|---|
| Ordinary folder (not a Git repository) | Disabled (greyed out) |
| Normal Git repository | Enabled |
Uncommitted changes on switch
If the working tree has uncommitted changes, the confirmation dialog offers three options:
| Option | What it does |
|---|---|
| Commit to current branch (default) | Opens a lightweight commit panel; select files, write a message, commit, then switch |
| Stash changes | Stashes current changes (including untracked files), then switches |
| Discard changes | Abandons all uncommitted changes, with a second confirmation |
Commit is the default for good reason
Committing is the safest of the three: the change is in history and retrievable at any time.
A stash is also retrievable, but stash stacks are easy to forget — especially when the tool did the stashing rather than you.
Discarding is genuinely gone. It asks twice; take that seriously.
Two safeguards:
- If the switch fails, the working tree rolls back completely to its prior state with no half-applied mess
- Choosing a remote branch creates and tracks a same-named local branch automatically, then switches to it. If a local branch of that name already exists, you are asked to name it yourself.
Branch display during execution
Inside an existing task's conversation, the workspace status bar shows the currently checked-out branch live, refreshing when it changes.
That display matters more than it looks: with several tasks in flight, "which branch is this agent actually editing" is the easiest thing to lose track of.
2. Worktree tasks
What it is
A worktree task uses Git's native worktree capability to give each parallel task a fully isolated working directory, while sharing branches and Git objects with the main repository.
Use it when you need to push several independent pieces of work forward at once — a new feature, a bug fix, an experimental approach — without them interfering with your current working directory.
Without it, two agents editing files in the same directory overwrite each other and produce an unreadable diff.
Creating one
- Enter your instruction on the new-task page
- With a
.gitdirectory in the workspace, a worktree toggle appears below the input box (off by default) - Turning it on expands a base branch selector, defaulting to the local main branch (e.g.
main), switchable to other local or remote branches, with search and fetch refresh - Send the instruction; creation begins with live progress (a large project can take tens of seconds to a minute)
- When creation completes, the agent starts and executes your instruction
Creation does three things automatically:
- Creates an isolated worktree directory under
~/WorkBuddy/Worktrees - Creates a task branch from the selected base branch's HEAD commit, named
workbuddy/{base}-{8-char hash}(e.g.workbuddy/main-a3f8c2b1). Theworkbuddy/prefix distinguishes them from branches you created - On failure, rolls back the worktree and branch it had created, leaving no half-built resources
Three constraints
- Non-Git projects (no
.git) show no worktree toggle — only ordinary tasks are possible - The base branch locks after creation; the task branch also cannot be switched during the task's lifetime
- Uncommitted changes in the source working tree do not prevent creation, but the new task starts from the base branch's HEAD commit and does not include them
The third one catches people: half-finished code on your desk does not travel into the worktree. To bring it, commit it or stash and apply.
Task identification
Worktree tasks are clearly marked in the list and detail pages:
- Type marker — a distinctive fork icon before the title in the task list; tasks still group under their original project
- Branch badge — next to the task card and title (e.g.
workbuddy/main-a3f8c2b1), read-only, hover for detail, click to copy
Automatic cleanup
To stop worktree tasks accumulating disk usage, there is a cleanup policy (for worktree tasks only — ordinary task creation is unrestricted):
| Count | Behaviour |
|---|---|
| 25 | Creating a new worktree task shows a "quite a lot of these" notice suggesting cleanup |
| 50 | Ticking worktree raises a "task workspace limit reached" dialog requiring a cleanup scope (branches and files older than 7 / 15 / 30 days) before you can continue; cancelling blocks creation |
Do not wait for 50
Every worktree is a complete copy of a working directory. On a large project, 50 of them eat a serious amount of disk.
Make it a habit: clean up when the task is done and the branch is merged. Or handle it at the 25-task notice.
When to use a worktree
| Ordinary task | Worktree |
|---|---|
| Light changes, single lookups | Several tasks running in parallel |
| One agent working | Several agents editing code at once |
| The change merges straight back | Isolating an experiment you may throw away |
| Small project — creating a worktree is not worth it | Large project where mixed diffs become chaos |
The official wording: use ordinary tasks for light changes and single lookups; turn on worktree when you need parallel work or an isolated experiment.
Creating a worktree on a large project takes tens of seconds to a minute — not worth it for one small edit.
A practical pattern
Say you want to push three things at once: fix a production bug, build a feature, try a refactor.
Task A (worktree, base: main)
Fix the white screen on the login page in Safari. Reproduce it before changing anything.
Task B (worktree, base: develop)
Add a config export to the settings page, following the format conventions in docs/api.md.
Task C (worktree, base: main)
Try replacing Redux with Zustand for state management. Only touch src/store; leave components alone.Three tasks in three isolated directories with three independent branches. If C falls apart, delete the branch; A and B are untouched.
FAQ
How do worktree changes get merged back?
Standard Git. The task branch is a real branch — push, open a PR, merge, all as usual. That is what "built on native Git semantics" means.
Can I open a worktree directory in an IDE?
Yes. Everything under ~/WorkBuddy/Worktrees is an ordinary working directory. Right-click → open folder from the task list also gets you there.
Does cleanup delete commits on those branches?
Cleanup removes the worktree directory and the associated task branch. Commits on a branch that was never merged or pushed elsewhere go with it. Merge or push anything important first.
What is not supported yet?
The docs mark this as V1 with some capabilities still in progress; trust what your client does.
End of the deep dives
Two routes from here:
- Something to copy today → Playbooks
- Look something up → FAQ, Troubleshooting, Glossary