name: git-worktree-prepare description: Create or reuse a dedicated git worktree for a branch using a deterministic path layout
Git Worktree Prepare
Create (or reuse) a dedicated worktree for a target branch so multiple agents can work in parallel without branch checkout conflicts.
Shell Compatibility
- Commands should work in both bash and zsh.
- Do not use
statusas a shell variable name (read-only in zsh). Useworktree_stateinstead.
Path Layout
Worktree root is always:
{repo-root}/.opencode/.bbq-worktrees
Worktree path for a branch:
{repo-root}/.opencode/.bbq-worktrees/{branch-name-with-slashes-replaced-by-dashes}
Example:
repo root: /Users/me/projects/my-repo
branch: feat/STU-15-user-authentication
worktree: /Users/me/projects/my-repo/.opencode/.bbq-worktrees/feat-STU-15-user-authentication
Inputs
branch(required): target branch name, for examplefeat/STU-15-user-authentication
Steps
Resolve repository context:
git rev-parse --show-toplevelResolve default branch from remote HEAD (do not hardcode
main):git symbolic-ref refs/remotes/origin/HEADParse to
origin/<default-branch>.Fallback strategy if remote HEAD is unavailable:
- Prefer
mainif it exists - Otherwise use
masterif it exists
- Prefer
Check whether this branch is already attached to any worktree:
branch="{branch}" existing_path="" current_path="" while IFS= read -r line; do case "$line" in "worktree "*) current_path="${line#worktree }" ;; "branch refs/heads/"*) current_branch="${line#branch refs/heads/}" if [ "$current_branch" = "$branch" ]; then existing_path="$current_path" break fi ;; esac done < <(git worktree list --porcelain)If found, return that path with worktree state
reusedand stop.Build deterministic worktree path:
- Resolve
repo_rootfromgit rev-parse --show-toplevel - Set
worktree_root="$repo_root/.opencode/.bbq-worktrees" - Replace
/with-in branch name for directory name - Create parent directories as needed
Example extraction flow:
repo_root="$(git rev-parse --show-toplevel)" worktree_root="$repo_root/.opencode/.bbq-worktrees" branch_slug="${branch//\//-}" worktree_path="$worktree_root/$branch_slug"- Resolve
Add the worktree:
- If local branch exists:
git worktree add "{worktree-path}" "{branch}" - Else if remote branch exists:
git worktree add --track -b "{branch}" "{worktree-path}" "origin/{branch}" - Else create a new branch from remote default branch:
git worktree add -b "{branch}" "{worktree-path}" "origin/{default-branch}"
- If local branch exists:
Verify:
git -C "{worktree-path}" branch --show-currentSync local-only files/directories from the source checkout:
- Read allowlist from
"{repo-root}/.opencode/worktree-local-files" - For each listed path:
- If source exists and target is missing, mirror it into the worktree
- Prefer symlink (
ln -s) so updates in source are reflected everywhere - Fallback to copy (
cp -R) if symlink is not possible
- Never overwrite existing files in the worktree
source_root="$(git rev-parse --show-toplevel)" worktree_path="{worktree-path}" sync_list="$source_root/.opencode/worktree-local-files" linked_count=0 copied_count=0 if [ -f "$sync_list" ]; then while IFS= read -r rel || [ -n "$rel" ]; do case "$rel" in ""|\#*) continue ;; esac src="$source_root/$rel" dst="$worktree_path/$rel" if [ ! -e "$src" ] || [ -e "$dst" ]; then continue fi mkdir -p "$(dirname "$dst")" if ln -s "$src" "$dst" 2>/dev/null; then linked_count=$((linked_count + 1)) else cp -R "$src" "$dst" copied_count=$((copied_count + 1)) fi done < "$sync_list" fi- Read allowlist from
Output
Return:
Branch: <branch>
Worktree: <absolute-path>
Worktree state: <created|reused>
Default base: origin/<default-branch>
Local files linked: <count>
Local files copied: <count>
Notes
- Do not use
git checkout -bin the current working tree when parallel work is expected. - Reusing an existing branch worktree is preferred over creating duplicates.
- Keep
.opencode/worktree-local-fileslimited to local-only files (for example.env*). init.shauto-discovers common.env*files and appends exact repo-relative paths to this list.