Handmade by Devvrat. All rights reserved.
A normal checkout holds one branch. You switch branches, and Git replaces the files in that folder. A second task in that folder then edits the wrong branch.
A git worktree is another folder for the same repository. You check out a second branch there. The first folder stays on its branch. Both folders share one commit history.
GitHub stores the branch and the pull request. The worktree stays on your machine. You push from the worktree folder.
The clone is the main worktree. git worktree add creates a linked worktree.
A linked worktree gets its own files, its own index, and its own HEAD. A commit in one folder shows up in the other folder.
Each new folder starts with tracked files only. Copy .env into it. Install dependencies there. pnpm links the second install from its store on the machine.
Git allows one branch in one worktree. A second checkout fails:
fatal: 'feat/billing-page' is already used by worktree at '/src/billing-page'Stay on main in the clone. Give the new folder a new branch with -b. A command without -b checks out the branch you name. Git refuses when that branch is already checked out.
Create the folder and the branch. The last argument is the start commit.
git worktree add -b fix/login-timeout ../login-fix mainGit creates ../login-fix and checks out fix/login-timeout there. Put the folder next to the clone. A path inside the clone shows up as untracked files.
Check out a branch that already exists:
List the worktrees. The first line is the main worktree.
/src/web abc1234 [main]
/src/billing-page def5678 [feat/billing-page]
/src/login-fix 9012abc [fix/login-timeout]Remove a clean worktree. The command deletes the folder. The branch stays.
Git refuses when the folder has changes or untracked files. Commit first. --force deletes uncommitted files. A worktree with submodules also needs --force.
If you delete the folder outside Git, prune the record from the main worktree:
If Git says the worktree is locked, unlock it, then remove it.
git worktree unlock ../login-fix
git worktree remove ../login-fixPush the branch before you remove the worktree. git worktree remove --force deletes uncommitted
files. The branch stays in the repository.
A feature is feat/slug. A bug fix is fix/slug. The slug is lowercase, with hyphens. The full rules are in Name branches like commits.
Read the name inside the worktree before the first push.
Rename the current branch when the name is wrong:
Give each task a different set of files. The folders stay separate. A merge still conflicts when both branches edit the same lines.
From the main checkout:
git fetch origin
git worktree add -b feat/billing-page ../billing-page origin/main
git worktree add -b fix/login-timeout ../login-fix origin/mainThe main checkout in this example is web. From each new folder:
cp ../web/.env .env
pnpm installPort 3000 belongs to one app. Start the other on port 3001.
Open http://localhost:3000 for one app. Open http://localhost:3001 for the other.
Start one agent in each folder. Tell it the branch name and the files it may edit. Then run git worktree list and confirm the names.
Work inside the folder that holds the branch.
git status -sb
git diff
git push -u origin HEAD
gh pr create --base main \
--title "Fix the login timeout" \
--body "Stop the login request after 10 seconds and show an error."Read the file list on GitHub. Each pull request contains the files for its own task.
Merge on GitHub. Then remove the folder and the local branch:
git worktree remove ../login-fix
git branch -d fix/login-timeoutgit branch -d refuses a branch that is not merged. Stop there. Those commits belong on the remote before you use -D.
Keep the main checkout on main. Put each task on its own branch, in its own folder.
Copy .env into the new folder. Install dependencies there. Give the dev server its own port. Read git worktree list before you push. Open one pull request per folder. Remove the folder after the pull request merges.