Git worktrees for LLM-assisted development
As I've been experimenting with Gen AI-assisted programming, I've reached the point where I find it valuable to have multiple checkouts of my repo each running with their own coding agent. The advantage to doing this is that each agent is free to make its own modifications in its own branch without interfering with the work of other agents.
My workflow for this is based on git-worktree, which allows checking a repo out into multiple directories, but sharing the same git state (so if you pull main in a worktree directory, all other instances have the updated branch). The steps to do that are:
# Go to original repo
cd ~/.../myrepo
# Create a new `main-01` branch in a parallel `myrepo-01` directory, tracking main
git worktree add -b main-01 ../myrepo-01 main
# Move to new worktree
cd ../myrepo-01
# Need to do yarn install, and set up .env and so on
yarn install
...Git worktrees don't let you check out the same branch in two locations at once, so I've adopted main-01, main-02, etc as copies of the main branch which I can return to when I'm not working on a specific branch. Note that these don't track main so you need to hard reset to get them up to date:
# Fetch main
git fetch origin main:main
# Get onto the worktree main instance
git checkout main-01
# Sync
git reset --hard mainNow each worktree can have its own branch, and it's easy to open up separate instances of Claude Code, Cursor, whatever in each directory. I tend to open an instance of Cursor with its own embedded Claude Code in each. On a Mac, ⌘-` lets me quickly toggle between instances of the same application. But it can be hard to quickly grok which instance I'm looking at, so I take an extra configuration step to visually distinguish each worktree. For this I use the VSCode Peacock extension, but it could also be managed manually if you don't want to install another extension.
First, I add the following to my .gitignore (this is checked in so I only have to do it once):
# Worktree-specific settings can be stored here without affecting the main repo.
worktree.code-workspace Then I paste the following into worktree.code-workspace and then "open workspace" when prompted (you could also paste a version with an empty settings block but this changes the style immediately to let you know it's configured correctly):
{
"folders": [
{
"path": "."
}
],
"settings": {
"peacock.color": "#497df5",
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#79a0f8",
"activityBar.background": "#79a0f8",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#d40b49",
"activityBarBadge.foreground": "#e7e7e7",
"commandCenter.border": "#e7e7e799",
"sash.hoverBorder": "#79a0f8",
"statusBar.background": "#497df5",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#79a0f8",
"statusBarItem.remoteBackground": "#497df5",
"statusBarItem.remoteForeground": "#e7e7e7",
"titleBar.activeBackground": "#497df5",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.inactiveBackground": "#497df599",
"titleBar.inactiveForeground": "#e7e7e799"
}
}
}Note that in the future, you should open your worktrees by referencing this file, e.g. cursor ./worktree.code-workspace .
I haven't run into this yet, but I believe that workspace-specific settings changes in Cursor/VSCode will all propagate to worktree.code-workspace so if you do make a change you want to share with all developers on the project, I think you'll need to copy the changes back to .vscode/settings.json manually.
Peacock has a "surprise me with a random color" command in ⌘-shift-P which will update the values in the config to a random theme. This is useful to get a quick color scheme for each instance.

I tend to think more visually so it's helpful for me to associate work with specific colors, e.g. "I'm working on reports in the orange space", "I'm updating terraform in blue", etc, etc.

With this setup, I generally feel comfortable letting agents run in accept edits mode. When they complete their task, I commit the changes (I generally want to be in control of commits and explicitly tell them not to commit automatically) then I push the changes to github and perform a review there.