Parallel Development with Git Worktrees and Codex CLI
Today I wanted Codex to simultaneously handle different features within the same repository since their tasks didn't overlap significantly. My goal was to open separate pull requests for each feature without interference, making it easier to review and resolve merge conflicts. Also, if Codex accidentally made a significant deletion or refactor unexpectedly, I wouldn't lose work on multiple tasks. So I was hoping for an efficient way to isolate git-staged files.
Fortunately, Git includes a built-in feature called worktree
, which I hadn't previously utilized. Git worktrees allow multiple isolated working directories, each connected to a distinct branch—perfect for enabling multiple Codex agents to independently develop features concurrently.
Understanding Git Worktrees
Git worktrees allow multiple directories to exist, each checked out to a separate branch while still sharing a common Git history. Unlike multiple repository clones, worktrees reuse a single .git
database, making them exceptionally lightweight and disk-efficient.
Benefits
- Parallel Branch Development: Seamlessly manage multiple branches without constant committing or stashing.
- Efficient Disk Usage: Avoids duplicating Git objects, significantly saving disk space.
- Independent Environments: Each worktree is completely isolated, eliminating potential conflicts like
.git/index.lock
.
Setting Up Git Worktrees for Codex CLI
Step 1: Create a Worktree for a Feature Branch
To initiate a new worktree tied to a specific feature branch:
git worktree add ../feature-branch origin/main -b feature-branch
This command:
- Creates a directory at
../feature-branch
- Checks out a new branch named
feature-branch
based onorigin/main
Step 2: Launch Codex CLI
Navigate to your new feature directory and launch the Codex CLI:
cd ../feature-branch
codex
To handle multiple features at the same time:
git worktree add ../another-feature origin/main -b another-feature
cd ../another-feature
codex
Each Codex CLI instance operates independently, facilitating parallel feature development.
Step 3: Clean Up
Once a feature is complete, cleanly remove the corresponding worktree:
git worktree remove ../feature-branch
Note: This removes the worktree directory but leaves the branch untouched.
Ergonomic Worktree Organization
By default, git worktree
does not allow creating worktrees inside the main working directory (e.g., ./worktrees/
under your repo root). This is a Git design choice to prevent confusion and corruption. The most practical way to keep things tidy is to use a hidden sibling directory for your worktrees:
Hidden Sibling Directory
Create a hidden directory next to your repo to store all worktrees:
# From your main repo directory
mkdir -p ../.wt # One-time setup
# Add worktrees for features
git worktree add ../.wt/feature-login origin/main -b feature-login
git worktree add ../.wt/bugfix-timeout origin/main -b bugfix-timeout
All feature branches live in ../.wt/
, keeping your workspace clean. No need to add anything to .gitignore
since .wt
is outside the repo.
Remove a worktree when done:
git worktree remove ../.wt/feature-login
For advanced users: It's possible to use an embedded bare repo layout to keep all worktrees inside a single top-level folder, but this requires extra setup. Seemed too complicated to me.
Quick Reference & Tips
- List active worktrees:
git worktree list
- Remove a worktree:
git worktree remove <path-to-worktree>
- Prune stale entries (after manually deleting a folder):
git worktree prune
- Use relative paths in metadata:
git config --global worktree.useRelativePaths true
- Each worktree must have a unique branch.
- Use
git worktree remove
instead of manually deleting directories.