# Worktrees in the Factory App

Learn how to run Factory App sessions in separate Git worktrees while keeping your main project folder unchanged.

Use a worktree when you want Droid to work on another task without changing the files in your main project folder. The Factory App creates a separate working directory for the session, prepares it, and keeps it isolated from your other work.

Factory-managed worktrees are available for Git projects on your local machine and connected Droid Computers.

<Note>
  Worktrees require a Git repository. For folders that are not Git repositories, start the session without a worktree.
</Note>

## What is a worktree?

A Git repository can have more than one working directory at the same time. Each directory has its own files and current branch, while all of them share the same commit history.

You can think of your main project folder as your regular workspace and a worktree as a second workspace for a separate task. Changes in one workspace do not appear as uncommitted changes in the other.

This allows you to make file changes on the same repository in parallel sessions, without the changes interfering with each other.

### Key terms

<PropertyList>
  <Property name='Checkout'>
    A working directory that contains the repository files for a specific branch or commit.
  </Property>
  <Property name='Main checkout'>
    The project directory you selected in Factory. This is usually the checkout you already use in your editor and terminal.
  </Property>
  <Property name='Worktree'>
    A separate checkout of the same Git repository. It has its own working files but shares commits and branches with the main checkout.
  </Property>
  <Property name='Base branch'>
    The branch Factory uses as the starting point for a new worktree.
  </Property>
  <Property name='Setup profile'>
    Optional instructions that prepare a new worktree, give Droid initial context, or clean up services later.
  </Property>
</PropertyList>

## Create your first worktree

<Steps>
  <Step title="Select your project">
    Start a new session and choose the Git repository you want Droid to work on.
  </Step>

  <Step title="Choose New worktree">
    Open the **Worktree** selector in the composer. Choose **New worktree**.
  </Step>

  <Step title="Pick a starting branch">
    Use the branch selector to choose the base branch. Factory creates a new branch from it by default, without switching branches in your main checkout.
  </Step>

  <Step title="Review the options">
    Open the panel beside **New worktree** if you want to keep the worktree permanently, use an existing branch, or run a setup profile. You can leave the defaults in place for your first session.
  </Step>

  <Step title="Send your prompt">
    Factory creates the checkout, runs the selected setup profile, and starts Droid inside it. The session shows the creation progress and worktree path.
  </Step>
</Steps>

To work in the selected project directory instead, choose **Start without worktree**.

## Choose how long to keep it

Every Factory-managed worktree has a lifecycle:

<ComparisonTable label='Worktree lifecycles'>

|                         | Ephemeral                              | Persistent                           |
| ----------------------- | -------------------------------------- | ------------------------------------ |
| Best for                | A task you expect to finish soon       | An environment you plan to revisit  |
| Sessions                | Usually one                            | Can contain multiple                 |
| Automatic cleanup       | Eligible                               | Never                                |
| Available as a project  | No                                     | Yes                                  |

</ComparisonTable>

Choose **Ephemeral** for most isolated tasks. Choose **Persistent** when you want a long-lived checkout that appears in the project selector for future sessions.

Factory remembers your last lifecycle choice for the project.

## Choose how the branch works

By default, Factory creates a new branch from the base branch you selected. This is the simplest option because the new worktree owns its branch from the start.

To continue work on a branch that already exists, open the branch mode control and choose **Use existing branch**. The branch cannot be:

- The repository's default branch.
- Checked out in your main checkout or another worktree.

<Tip>
  If you are unsure which branch mode to use, keep the default. Git allows a branch to be checked out in only one worktree at a time.
</Tip>

## Prepare new worktrees automatically

A new checkout may need dependencies, generated files, or project-specific instructions before Droid can begin. A setup profile runs those tasks each time Factory creates a worktree for the project.

<Steps>
  <Step title="Choose a project">
    Open **Settings → Worktrees** and select a project under **Setup profiles**.
  </Step>

  <Step title="Create a profile">
    Select **Add profile** and enter a name. Add at least one setup script, initial prompt, or cleanup script.
  </Step>

  <Step title="Use the profile">
    In the new-session composer, open the panel beside **New worktree** and select the profile. Factory preselects the last profile you used for that project.
  </Step>
</Steps>

Each profile can contain:

<PropertyList>
  <Property name='Setup script'>
    Runs from the root of the new worktree before the session starts. Use it to install dependencies or prepare local tooling.
  </Property>
  <Property name='Initial prompt to Droid'>
    Gives Droid project-specific instructions before it receives your session prompt. Your prompt waits until this instruction finishes.
  </Property>
  <Property name='Cleanup script'>
    Runs from the worktree root before Factory removes the checkout. Use it to stop services or remove external resources created during setup.
  </Property>
</PropertyList>

Setup and cleanup scripts can use `REPO_ROOT_PATH` to find the main checkout. Factory removes credentials and Factory-specific environment variables before running profile scripts.

### Share a profile with your repository

Profiles created in the app stay on the selected machine. To give everyone in the repository the same profile, commit a `.yaml` or `.yml` file under `.factory/worktree-setups/`:

```yaml title=".factory/worktree-setups/node.yaml"
name: Node.js setup
script: |
  set -euo pipefail
  pnpm install
initial_prompt: Read the repository instructions before starting.
cleanup_script: |
  docker compose down
```

The supported fields are `name`, `script`, `initial_prompt`, and `cleanup_script`. Shared profiles are read-only in the app. Edit their YAML files in the repository to change them.

## Include local files that Git ignores

A worktree starts with the files tracked by Git. Local files excluded by `.gitignore`, such as `.env.local`, are not present automatically.

To copy selected ignored files into each new Factory-managed worktree, create `.worktreeinclude` in the root of your main checkout. List one repository-relative path or directory per line:

```text
# Local environment and tool configuration
.env.local
local/
```

Blank lines and lines that begin with `#` are ignored. Directories are copied recursively. Factory copies matching files before running the setup profile, so the setup script can use them.

Only paths already ignored by Git are eligible. Factory skips:

- Tracked or unignored paths.
- Missing files and directories.
- Absolute paths and paths outside the repository.
- Symbolic links.
- Files that already exist in the new worktree.

<Warning>
  Review each path before adding it. Files ignored by Git can still contain credentials or other sensitive data.
</Warning>

## Manage and remove worktrees

Open **Settings → Worktrees** to:

- Change the worktree directory. The default is `~/.factory/worktrees`.
- Set the number of ephemeral worktrees Factory keeps. The default limit is 15.
- Browse managed worktrees by repository and machine.
- Check each worktree's path, size, lifecycle, and active sessions.
- Delete a worktree you no longer need.

You can also delete a worktree from its sidebar menu. Before you confirm, Factory shows any uncommitted changes, untracked files, and unpushed commits it found. Removing the local branch or remote branch is a separate choice.

When you archive the last session in a worktree, Factory asks whether to delete the worktree. If you confirm, Factory runs its cleanup script, removes the checkout, and archives the associated sessions. If you cancel, Factory keeps both the session and the worktree.

### How automatic cleanup works

When Factory prepares a new worktree, it checks whether the new worktree would exceed your ephemeral worktree limit. If so, Factory starts cleanup with the least recently used ephemeral worktree and skips that worktree if it has:

- An active or recently used session.
- Uncommitted changes or untracked files.
- An open pull request.
- Unpublished commits, unless the related pull request is merged.

If Factory skips a worktree, it checks the next one until it removes enough worktrees to meet the limit. Persistent worktrees do not count toward the limit.

### How orphan maintenance works

Factory also runs a background maintenance sweep to reconcile sessions, worktrees, and Git metadata. The sweep runs after you archive a session and periodically when Factory refreshes the session list. It completes three passes in order:

1. **Archive sessions with missing worktrees.** If a session points to a worktree directory that no longer exists, Factory archives the session. If the configured worktree root is unavailable, Factory leaves the session unchanged.
2. **Remove orphaned worktrees.** Factory looks for managed worktrees that no session references. It preserves worktrees that are in use, persistent, referenced by any session, or waiting for a cleanup retry. Factory reloads the session list immediately before removal and preserves uncommitted changes or untracked files. This pass does not block on unpublished commits or pull request status because it removes only the worktree directory, not its branch.
3. **Clear leftover metadata.** Factory removes empty managed worktree group directories and asks Git to prune stale worktree records for repositories found in session metadata.

Automatic cleanup removes the checkout, not its Git branch.

## Frequently asked questions

### Why is my `.env` file missing?

Git worktrees contain tracked files. If Git ignores the file, add its path to [`.worktreeinclude`](#include-local-files-that-git-ignores) so Factory copies it into future worktrees.

### Does deleting a worktree delete its branch?

Not automatically. Factory treats removal of the checkout, local branch, and remote branch as separate actions. Automatic cleanup removes only the checkout.

### Where does Factory store worktrees?

Factory uses `~/.factory/worktrees` by default. Change the location under **Settings → Worktrees**.

<RelatedLinks>
  <RelatedLink href='/factory-app/settings' title='App settings'>
    Configure personal defaults for Factory App sessions.
  </RelatedLink>
  <RelatedLink href='/droid-cli/cli-reference#git-worktrees' title='CLI Git worktrees'>
    Start isolated worktree sessions from the Droid CLI.
  </RelatedLink>
  <RelatedLink href='/factory-app/quickstart' title='Factory App quickstart'>
    Install the app and start a reviewable Droid session.
  </RelatedLink>
  <RelatedLink href='/harness/agents-md' title='Configure AGENTS.md'>
    Give every worktree session your repository instructions.
  </RelatedLink>
</RelatedLinks>
