Git Worktree
Why would you want to use it? To be able to checkout multiple branches at the same time without having to clone your repo.
Currently if you run git worktree list you’d see that you only have one git-worktree. e.g. I get the following
/Users/mfaani/Developer/project-iOS 0960933f [main]
The commit and branch name show the current HEAD; if you were on another branch, the worktree would show that branch instead.
So if you wanted to add another worktree then you’d just have to do:
git worktree add ../myNewWorkTreePath <branch>
NOTE: You’d definitely want to run the above command from the root directory of your project. Otherwise you’d be creating a directory that is within your git worktree and can get committed. You don’t want that. I usually use these steps:
- create a parent directory for your repo
- put the repo’s top level in that.
ATTENTION: if you copy and paste paths from Finder, make sure you include hidden items like the
.gitdirectory. Otherwise git will think you moved the entire project to a different folder and create stupid diff for you
- create the new worktree.
git worktree add ../new-worktree branch-name
That way I have both worktrees at the same level again
Important Note: At any given moment, a branch can only be checked out in one worktree. If you try to checkout a branch that is already checked out on a different worktree then you’ll get
fatal: ‘branchB’ is already checked out at ‘/path/to/oneLevelAboveRootProject/treeA’
each added work-tree has its own index and HEAD, the HEAD files wind up sharing the underlying branch pointers in the shared repository
How does AI use worktrees?
I recently asked Codex to run 4 tasks in parallel. Codex did that by creating 4 git worktrees.
What was interesting was, Codex didn’t create the worktree next to my current directory. It created them under .codex directory instead. The output of running git worktree list was:
/Users/mfaani/Developer/project-iOS 2696557 [main]
/Users/mfaani/.codex/worktrees/036d/project-iOS 7db4714 (detached HEAD)
/Users/mfaani/.codex/worktrees/14df/project-iOS e0cebf8 (detached HEAD)
/Users/mfaani/.codex/worktrees/28a0/project-iOS 48b8289 (detached HEAD)
/Users/mfaani/.codex/worktrees/6b54/project-iOS c8bc3e9 (detached HEAD)
Once all tasks were finished, I used the original parent task and asked it to merge all the work that was done in the individual worktrees. It ended up create 4 commits.
Why is it using detached head?
First know what a detached head is.
Because you can’t checkout your main branch into 4 worktrees, then you’re left with two choices:
- Create 4 branches
- Create 4 different worktrees pointing to a detached head.
Creating 4 branches is more intrusive. Because then if you run your git branch command, you’d end up seeing new branches that you probably don’t want to have.
Why not just use branches instead of worktrees?
Each worktree has its own working tree for files, build artifacts, uncommitted changes, index, and checked-out branch, while still sharing the underlying Git repository/history.
Had you used git branch for every task, then because you’re using a single working tree, the agent would have to constantly switch between branches to be able to commit changes and parallel building would be impossible.
When does Codex remove the worktrees it created?
This one I’m not sure. But you can remove it yourself. Follow steps from here. I suppose if you also deleted a task then the associated worktree is removed. Not sure.