tencent cloud

Git Worktree Support

Download
Focus Mode
Font Size
Last updated: 2026-09-30 18:41:46
AI-Translated

Overview

Git worktree allows you to have multiple working directories in the same repository simultaneously, with each directory checking out a different branch. CodeBuddy Code leverages this feature to provide:
Parallel development: Conduct experimental development without affecting the main workspace.
Security isolation: All changes made by AI are performed in an isolated directory.
Zero storage overhead: Worktrees share Git objects and do not copy the entire repository.
Subagent isolation: Supports multiple AI subagents working in parallel in separate worktrees.
tmux integration: Optionally run in a separate tmux session.
Non-Git support: Through WorktreeCreate/WorktreeRemove hooks, projects such as SVN and Perforce can also use worktree isolation.

Quick Start

# Create a worktree with an auto-generated name
codebuddy --worktree

# Create a worktree with a specified name
codebuddy --worktree feature-auth

# Create a worktree with a specified base branch
codebuddy --worktree --worktree-branch origin/develop # Based on the remote develop branch
codebuddy --worktree --worktree-branch feature/foo # Based on the local feature/foo branch

# Run in a tmux session (recommended for long-running tasks)
codebuddy --worktree --tmux

# Create a worktree based on a PR/MR (for code review)
codebuddy --worktree "#123" # GitHub PR number
codebuddy --worktree "https://github.com/owner/repo/pull/123" # GitHub PR link
codebuddy --worktree "https://gitlab.com/owner/repo/-/merge_requests/456" # GitLab MR link
codebuddy --worktree "https://cnb.woa.com/owner/repo/-/pulls/789" # CNB PR link

Creating in a Session

After a CodeBuddy Code session is started, you can request to create a worktree using natural language:
> start a worktree
> work in a worktree
> Start a worktree
AI automatically calls the EnterWorktree tool to create an isolated working directory and switch to it.
Note:
It is triggered only when "worktree" is explicitly mentioned. Saying "create a branch for me" or "fix this bug" does not automatically create a worktree.

CLI Parameters

Parameter
Description
Example
--worktree [name]
Create and enter the worktree.
--worktree or --worktree my-feature
--worktree-branch <branch>
Specify the base branch (must be used with --worktree).
--worktree-branch origin/develop or --worktree-branch feature/foo
--tmux
Run in a tmux session (requires tmux to be installed).
--worktree --tmux
--tmux-classic
Use classic tmux mode (without popup).
--worktree --tmux --tmux-classic

Workflow

Creating a Worktree

When started with the --worktree parameter:
1. CodeBuddy creates a new worktree in the .codebuddy/worktrees/ directory.
2. Specify the base branch:
If --worktree-branch origin/xxx is specified, the worktree is based on the remote branch origin/xxx.
If --worktree-branch xxx is specified, the worktree is based on the local branch xxx.
If not specified, the worktree is based on the remote default branch by default, typically origin/main or origin/master.
3. Automatically create the corresponding branch, such as worktree-feature-auth.
4. Switch the working directory to the worktree. If you started from a subdirectory of the repository, you will first go to the corresponding relative subdirectory in the new worktree.
5. Run initialization, including copying settings, creating symbolic links, and copying the .worktreeinclude file.
Behavior When the Branch Does Not Exist:
If the specified branch (remote or local) does not exist, a warning is printed and the system automatically falls back to the remote default branch to continue creation.
The startup process is not interrupted.

Choices on Exit

When you exit a worktree session, CodeBuddy detects changes and provides options:
Keep Worktree: Keep all changes and branches so you can continue later.
Delete Worktree: Clean up the worktree and its associated branches.
Keep but Exit tmux: In tmux mode, keep the worktree but close the tmux session.

Change Detection

Before exiting, CodeBuddy detects:
Uncommitted file changes
Unpushed commits
If there are no changes, the worktree is automatically cleaned up.

Configuration

Configure worktree behavior in settings.json:
{
"worktree": {
"symlinkDirectories": ["node_modules", ".next", ".cache", "dist"]
}
}

Configuration Item

Configuration Item
Description
Default Value
symlinkDirectories
Directories symbolically linked from the main repository to the worktree
[]
Symbolic link directories prevent dependencies from being installed repeatedly in each worktree, saving time and disk space.

Synchronizing the Local Ignore File (.worktreeinclude)

Local configuration files such as .env.local and .env.development are typically excluded by .gitignore, but they are also required in a new worktree for it to run properly.
Solution: Create a .worktreeinclude file in the repository root directory and list the files to copy, using the same syntax as .gitignore:
# .worktreeinclude
# List local files to copy to the new worktree

# Environment variables
.env.local
.env.development.local
.env.test.local

# Local IDE configuration
.vscode/settings.json

# Local certificates or keys (if any)
certs/localhost.pem
Each time a new worktree is created, these files are automatically copied from the root directory of the main repository. They are not copied again when an existing worktree is reused.
Note:
.worktreeinclude should be committed to Git so that all team members can benefit from it.

Hook-based Worktree

By default, the worktree feature relies on Git's built-in git worktree command. For projects using SVN, Perforce, or no version control, you can use the worktree isolation feature by configuring WorktreeCreate / WorktreeRemove hooks.

Decision Priority

1. Is a WorktreeCreate hook configured? → Use the hook to create (the hook is preferred even in Git repositories).
2. In a Git repository? → Use git worktree.
3. None of the above? → Report an error and prompt to configure a hook.
Core rules:
Hooks take precedence over Git: after a WorktreeCreate hook is configured, the hook is used even in Git repositories instead of git worktree.
No fallback on creation failure: if the WorktreeCreate hook fails, the system does not fall back to git worktree and reports an error directly.
Deletion failure does not block: if the WorktreeRemove hook fails, only a warning is logged and the exit process is not blocked.

Configuration Method

Configure in .codebuddy/settings.json (project-level) or ~/.codebuddy/settings.json (global):
{
"hooks": {
"WorktreeCreate": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.codebuddy/hooks/worktree-create.sh"
}
]
}
],
"WorktreeRemove": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/.codebuddy/hooks/worktree-remove.sh"
}
]
}
]
}
}
The two hooks are configured independently. You can configure only WorktreeCreate without WorktreeRemove, in which case no automatic cleanup is performed on exit and you will be prompted to delete the directory manually.

Input Data (stdin)

The Hook script receives context data in JSON format through stdin.
WorktreeCreate input:
{
"hook_event_name": "WorktreeCreate",
"session_id": "abc123def456",
"cwd": "/Users/user/project",
"transcript_path": "/Users/user/.codebuddy/sessions/abc123/transcript.md",
"name": "feature-auth"
}
Field
Description
name
worktree name (user-specified or automatically generated by the system)
cwd
Current Working Directory
session_id
Current Session ID
transcript_path
Transcript File Path
WorktreeRemove input:
{
"hook_event_name": "WorktreeRemove",
"session_id": "abc123def456",
"cwd": "/Users/user/project",
"transcript_path": "/Users/user/.codebuddy/sessions/abc123/transcript.md",
"worktree_path": "/tmp/codebuddy-worktrees/feature-auth"
}
Field
Description
worktree_path
Absolute path of the worktree to delete

Output and Exit Code

WorktreeCreate:
stdout: must output the absolute path of the created worktree, taking the last non-empty line.
stderr: can output logs without affecting path parsing.
exit code 0: success, parse the path from stdout.
Non-zero exit code: creation fails, an error is reported, and the process exits without falling back to git worktree.
# Correct example: logs are output to stderr, and the path is output to stdout.
echo "Initializing SVN checkout..." >&2
echo "/home/user/.codebuddy/worktrees/feature-auth"
WorktreeRemove:
No decision control: no exit code will prevent the exit process.
On failure, only a warning log is recorded.

Exit Behavior Differences

Unlike Git worktree, hook-based worktree always displays the keep/remove menu upon exit and does not perform change detection, because non-Git projects do not have git status.

Hook Script Template

WorktreeCreate (~/.codebuddy/hooks/worktree-create.sh):
#!/bin/bash
set -e

INPUT=$(cat)
NAME=$(echo "$INPUT" | jq -r '.name')
CWD=$(echo "$INPUT" | jq -r '.cwd')

WORKTREE_PATH="$HOME/.codebuddy/worktrees/$NAME"
mkdir -p "$WORKTREE_PATH"

# Add VCS initialization logic here (SVN checkout, P4 sync, directory copy, etc.)
cp -r "$CWD"/* "$WORKTREE_PATH/" 2>/dev/null || true

# Output the absolute path to stdout on the last line (required)
echo "$WORKTREE_PATH"
WorktreeRemove (~/.codebuddy/hooks/worktree-remove.sh):
#!/bin/bash

INPUT=$(cat)
WORKTREE_PATH=$(echo "$INPUT" | jq -r '.worktree_path')

# Security check: ensure the path is within the expected range.
if [[ "$WORKTREE_PATH" != "$HOME/.codebuddy/worktrees/"* ]]; then
echo "Refusing to remove path outside worktrees directory: $WORKTREE_PATH" >&2
exit 1
fi

rm -rf "$WORKTREE_PATH"
Note:
The script depends on jq to parse JSON. macOS: brew install jq, Linux: apt install jq.

Practical Examples

SVN project:
{
"hooks": {
"WorktreeCreate": [
{
"hooks": [
{
"type": "command",
"command": "bash -c 'INPUT=$(cat); NAME=$(echo $INPUT | jq -r .name); DIR=\\"$HOME/.codebuddy/worktrees/$NAME\\"; svn checkout https://svn.example.com/repo/trunk \\"$DIR\\" >&2 && echo \\"$DIR\\"'"
}
]
}
],
"WorktreeRemove": [
{
"hooks": [
{
"type": "command",
"command": "bash -c 'cat | jq -r .worktree_path | xargs rm -rf'"
}
]
}
]
}
}
Projects without VCS (directory copy):
{
"hooks": {
"WorktreeCreate": [
{
"hooks": [
{
"type": "command",
"command": "bash -c 'INPUT=$(cat); NAME=$(echo $INPUT | jq -r .name); CWD=$(echo $INPUT | jq -r .cwd); DIR=\\"$HOME/.codebuddy/worktrees/$NAME\\"; cp -r \\"$CWD\\" \\"$DIR\\" && echo \\"$DIR\\"'"
}
]
}
],
"WorktreeRemove": [
{
"hooks": [
{
"type": "command",
"command": "bash -c 'cat | jq -r .worktree_path | xargs rm -rf'"
}
]
}
]
}
}

tmux Integration

You can run CodeBuddy in a separate tmux session by using the --tmux flag:
# Basic Usage
codebuddy --worktree --tmux

# Use traditional mode (without popup)
codebuddy --worktree --tmux --tmux-classic

tmux Requirements

tmux version 3.2 or later (with popup support)
If the version is lower, it automatically falls back to traditional mode.

Exiting a tmux Session

Press Ctrl+D or type /exit to exit CodeBuddy.
The tmux session will be kept or closed based on your choice.

Directory Structure

your-repo/
├── .codebuddy/
│ └── worktrees/
│ ├── feature-auth/ # worktree directory
│ │ ├── node_modules -> ../../node_modules # symbolic link
│ │ └── ...
│ └── fix-bug-123/
├── .worktreeinclude # Defines local files to copy (recommended to commit)
└── ...

Manually Managing Worktrees

CodeBuddy Code automatically handles worktree cleanup when a session exits. However, manual management outside the session is sometimes required, such as cleaning up leftover worktrees or controlling branch and directory locations more flexibly.

Cleaning Up Worktrees Outside a Session

Clean up directly with Git commands:
# View all current worktrees
git worktree list

# Delete a specified worktree (when there are no uncommitted changes in the worktree)
git worktree remove .codebuddy/worktrees/feature-auth

# Force delete (when there are uncommitted changes)
git worktree remove --force .codebuddy/worktrees/feature-auth

# Also delete the corresponding branch
git branch -D worktree-feature-auth

# Clean up stale worktree references (the directory is deleted but Git still tracks it)
git worktree prune

Creating Worktrees Directly with Git

Sometimes you need to check out an existing branch or place the worktree outside the repository directory. You can bypass CodeBuddy Code and create it directly with Git, then start a session inside it:
# Create a new branch and a worktree (outside the repository)
git worktree add ../project-feature-a -b feature-a

# Check out an existing branch
git worktree add ../project-bugfix bugfix-123

# Enter the worktree and start CodeBuddy Code
cd ../project-feature-a && codebuddy

# Clean up after use
git worktree remove ../project-feature-a
This approach is suitable for scenarios where you need to place the worktree in a specific location or reuse an existing branch.

Sub-Agent Isolation

When having CodeBuddy Code launch multiple subagents to work in parallel, you can run each subagent in a separate worktree to avoid file conflicts.

What Is isolation: worktree?

Add isolation: worktree to the frontmatter of a custom Agent. Each time you launch this Agent with the Task tool, the system automatically creates a separate worktree for it instead of running it directly in the main repository directory.
This means that:
Multiple subagents can modify files with the same name simultaneously without affecting each other.
The main repository directory remains clean, and temporary changes made by subagents do not pollute it.
After a subagent completes, the worktree is kept or deleted as needed.

Creating an Isolated Custom Agent

Create a Markdown file in the .codebuddy/agents/ directory:
---
name: isolated-worker
description: Work in a separate worktree without affecting the main repository.
isolation: worktree
---

You are running in a separate git worktree.
Focus on completing the task assigned to you, and report the results when done.

Effectiveness

When the main Agent launches this Agent with the Task tool, it automatically creates a separate worktree for it. Multiple subagents can work simultaneously without conflicts even if they modify the same files.
After the subagent completes:
No changes: The worktree is automatically deleted.
Changes exist: The worktree is kept, and the main Agent receives the worktree location information.

Verifying Isolation Effectiveness

> Use the isolated-worker agent to create test.txt in the current directory and write "hello" to it.
Check results:
# This file does not exist in the main repository.
ls test.txt
# → No such file or directory ✓

# The file is in the subagent's worktree.
ls .codebuddy/worktrees/agent-xxx/test.txt
# → Exists ✓

Typical Use Cases

Scenario 1: Developing Based on a Specific Branch

Problem: New features need to be developed on the develop branch instead of the main branch.
Solution:
# Create a worktree based on the remote develop branch
codebuddy --worktree feature-xxx --worktree-branch origin/develop

# Create based on the local branch (preserving local unpushed commits)
codebuddy --worktree feature-yyy --worktree-branch my-local-branch

Scenario 2: Handling Urgent Bugs in Parallel

Problem: You are developing a new feature and have partially modified the code when an urgent bug suddenly needs to be fixed.
Solution:
# Terminal 1: Continue developing the new feature
codebuddy --worktree feature-payment

# Terminal 2: Dedicated to fixing bugs without interfering with each other
codebuddy --worktree hotfix-login-crash
Two worktrees can be open at the same time without affecting each other. After fixing the bug, submit a PR and then return to feature development.

Scenario 3: High-Risk Refactoring

Problem: You want to attempt a large-scale refactoring but are unsure whether it will succeed, and you do not want to pollute the main repository.
Solution:
codebuddy --worktree refactor-esm
In the session:
> Help me migrate the src/core directory from CommonJS to ESM
Result:
Success: Commit, push the PR, and merge.
Failure: Select "Remove worktree" when exiting to discard all changes at once.

Scenario 4: Reviewing Pull Requests

Problem: You want to run a colleague's PR code locally but do not want to pollute the working directory.
Solution:
codebuddy --worktree "#456"
In the session:
> Help me review what this PR changed and whether there are any potential issues.
> Run the tests
Exit directly after the review, and the worktree will be cleaned up automatically.

Scenario 5: Parallel Tasks

Problem: There are multiple independent tasks (writing documentation, adding tests, and developing new APIs) that you want to advance separately.
Solution:
codebuddy --worktree task-docs --tmux
codebuddy --worktree task-tests --tmux
codebuddy --worktree task-new-api --tmux
Each worktree lets the AI focus on one task, and with tmux you can achieve true parallel work.

Scenario 6: Subagent Collaboration

Problem: Large tasks require multiple AIs to process different modules in parallel.
Solution:
First, create an isolated Agent (see the Subagent Isolation section above), and then:
> Use three parallel api-worker subagents:
First, process the src/api/user/ directory.
Second, process the src/api/order/ directory.
Third, process the src/api/product/ directory.
The three subagents each work in an independent worktree, so there are no conflicts even when shared files are modified.

FAQs

Q1: --worktree-branch: Should It Be a Remote Branch or a Local Branch?

Strictly distinguish:
--worktree-branch origin/xxx → Use the remote branch (fetches the latest code first).
--worktree-branch xxx → Use the local branch (preserves local unpushed commits).
If the specified branch does not exist, a warning is printed and the system falls back to the remote default branch without interrupting startup.

Q2: Do Worktrees Take Up a Lot of Disk Space?

No. All worktrees share the Git object database and only need to store the working files themselves. If symlinkDirectories is configured, large directories are also shared and take up almost no additional space.

Q3: When an existing worktree is reused, Will Files Like .env.local Be Copied Again?

No. When reuse is performed, it directly enters the existing directory and skips initialization. To sync new configurations, delete the worktree and recreate it:
git worktree remove --force .codebuddy/worktrees/my-feature
git branch -D worktree-my-feature
codebuddy --worktree my-feature

Q4: Do Commits in a worktree Affect the Main Repository?

No. Each worktree has an independent branch, and commits are made only on that branch. To merge into the main branch, go through the normal PR process or manually run git merge.

Q5: What Should I Do If a worktree Creation Is Interrupted and Leaves an Incomplete Directory?

git worktree remove --force .codebuddy/worktrees/<name>
git branch -D worktree-<name>
Then recreate it.

Q6: symlinkDirectories Is Configured but Not Taking Effect?

Reusing an existing worktree does not reinitialize it. Delete the old worktree and recreate it once.

Q7: Is Subagent Isolation a Security Sandbox?

No. Subagents are isolated at the file level, but they have the same permissions as the main Agent and can theoretically operate on files outside the worktree. The purpose of this feature is to prevent file conflicts between multiple Agents, not to serve as a security restriction.

Q8: Can I Still Use Git Worktree After Configuring the WorktreeCreate hook?

They cannot be used at the same time. Hooks take precedence over Git. Once a WorktreeCreate hook is configured, all worktree operations go through the hook, even in Git repositories. To restore the use of git worktree, delete the WorktreeCreate configuration in settings.json.

Q9: What Happens If Only WorktreeCreate Is Configured but Not WorktreeRemove?

Creation works normally, but no automatic cleanup is performed on exit. The system prompts you where the worktree directory is retained, and you need to delete it manually.

Q10: What Should I Do If a Hook Script Fails to Execute?

If WorktreeCreate fails, an error is reported directly without falling back to git worktree. Check the script's stderr output to troubleshoot the issue. If WorktreeRemove fails, only a warning is logged, and the exit process is not affected.

Q11: Why Is There No Automatic Cleanup on Exit When Using hook-based worktree in a Non-Git Project?

When a hook-based worktree is exited, the keep/remove menu is always displayed, and change detection is not performed because non-Git projects do not have git status. You need to manually choose whether to delete it.

Must-Knows

Git repository or Hook: --worktree requires a Git repository or a configured WorktreeCreate hook (non-Git projects such as SVN and Perforce can be supported through the hook).
Branch naming: Automatically created branches use the worktree- prefix.
Cleanup: Worktrees that have not been used for a long time are not automatically cleaned up. You need to delete them manually or use the /rewind command.
Symbolic links: Some tools may not support directories that are symbolic links. Configure them based on your project requirements.

References

CLI Reference - Complete command-line parameter reference
Hooks Reference - Detailed documentation for the Hook system
Configure settings - Configuration file description


Help and Support

Was this page helpful?

Help us improve! Rate your documentation experience in 5 mins.

Feedback