Skip to main content

Code workflows

Branches and Worktrees

Every artifact in Spruce can have its own git branch and worktree — an isolated checkout of your code repo tied to that specific piece of work. This is how Spruce connects planning (artifacts) to code (branches) without forcing you to juggle git checkout between tasks.

Why worktrees (and not just branches)

A single checkout can only be on one branch at a time. If you're in the middle of implementing artifact A and someone asks you to look at artifact B, you'd have to stash, checkout, context-switch. With worktrees, each artifact gets its own checkout, so you can run dev servers and tests for multiple artifacts concurrently without interference.

Start

Open any artifact (typically a feature or task) and click Start in the top-right. Spruce:

  1. Creates a branch named after the artifact ID, e.g. artifact/SPR-abc123.
  2. Creates an isolated git worktree for that branch at <repo>/.worktrees/SPR-abc123/ (separate from your main checkout).
  3. Opens a terminal panel scoped to the worktree.

The worktree is a real git worktree; git worktree list inside the repo will show it.

What Start branches off

Start always tries to fork from the freshest base it can:

  1. Fetch first. Spruce fetches the artifact branch and the base branch (main by default, or the configured base) from origin. If there's no remote, it skips this step.
  2. Pick up an existing remote artifact branch. If a collaborator has already pushed artifact/SPR-abc123, Spruce creates the local branch tracking the remote (you start where they left off, not from base).
  3. Otherwise, fork from origin/<base>. This is the key rule: artifact branches are forked from the remote base, not your local one. If your local main is stale, Start still gives you a branch off the latest pushed main. (If there's no remote at all, Start falls back to local main.)

If the fetch fails (offline, auth, network), Start either errors or proceeds with whatever's local, controlled by the artifact's allowOffline flag.

Where worktrees live on disk

By default, worktrees go in a .worktrees/ directory inside the linked code repo, with one folder per artifact ID, e.g. <repo>/.worktrees/SPR-abc123/. Spruce adds .worktrees/ to the repo's .gitignore so the trees themselves don't get committed.

You can change the location in Settings → Per-project settings → Worktree storage path (leave it blank to use the default). See Per-Project Settings.

Git tab actions

The Git tab exposes a handful of operations that work against the artifact's branch and remote. They follow consistent rules, worth understanding because Spruce automates a few things git makes you think about by hand.

The Git tab does not have a "Sync" button. That's the project-sync flow (artifact-document syncing, in the sidebar header), which is unrelated to the code-repo's branch. The code-repo flow is commit, push, update from main, update from remote.

Commit and push

  • Commit stages all changes in the worktree and creates a commit with the message you provide.
  • Push pushes the artifact branch to origin/artifact/<id>. If the branch is fast-forward-able, the push goes through directly. If the branch and the remote have diverged (you've rewritten history, e.g. just rebased from main), Push shows a confirmation dialog before force-pushing. You confirm, Spruce force-pushes; you cancel, nothing happens. --force-with-lease isn't used (libgit2 doesn't expose it natively).

The implicit rule that keeps force-push safe is one artifact branch, one author at a time. If you're collaborating with an agent or a teammate on the same branch, coordinate with them rather than racing pushes.

Update from main

Update from main (⌘⇧R) rebases the artifact branch on top of origin/<base>:

  1. Fetches origin/<base> (typically main).
  2. Rebases the artifact branch onto the freshest base.
  3. Leaves you in a state where the next Push will need to force-push the rewritten history (with the confirmation dialog above).

If the rebase surfaces conflicts, Spruce shows the conflict-resolution UI; resolve and Continue Rebase, or Abort Rebase to bail. (The smart action surfaces "Update from main (conflicts)" if the rebase would conflict, useful early warning before you hit Update.)

Update from remote

Update from remote is the pull side: fetch the artifact branch from origin/artifact/<id> and rebase your local on top. Use this when an agent or a teammate has pushed to the same branch from another machine and you're now behind.

Open PR / merge

  • Create PR opens your git host (GitHub via gh, etc.) with the artifact branch pre-selected. The PR's base branch is whatever the artifact was forked from, typically main.
  • Merge to main does a local merge into the configured base branch. Useful for repos without a PR-driven workflow; squashes are not applied. The merge is a regular fast-forward / merge commit.

The merge / PR flow is being improved soon. Expect things like auto-update of main after merge, an integrated PR view inside Spruce, and more lifecycle automation. For now, the local merge is intentionally minimal.

Finish

Click Finish (longer label: Finish Working) at the bottom of the Git tab in the tool panel to:

  • Terminate all running sessions for the artifact. Every dev server, test runner, and agent session in the worktree gets killed.
  • Remove the worktree from disk.
  • Delete the associated local branch (only if the branch has been merged into the base, or is clean; Spruce blocks deletion if there are uncommitted changes, and refuses entirely if you somehow point at the base branch itself).

Note: Finish doesn't delete the remote branch if you've pushed. Use your git host's UI to clean up the remote after merging.

Multiple worktrees at once

There's no limit on the number of concurrent worktrees. Each gets its own terminal sessions, its own git state, and its own running processes. This is the parallelism that makes multi-agent workflows practical — each agent can take its own artifact into its own worktree.

From the Code page

When you navigate to a worktree's files on the Code page, Spruce shows the artifact chip for the worktree's branch so you can jump back to the artifact.