CLI Reference

The canopy CLI provides worktree management and AI tool integration from the terminal.

Table of contents

  1. Installation
  2. Shell integration
  3. Commands
    1. canopy add
    2. canopy list
    3. canopy status
    4. canopy reload
    5. canopy fetch
  4. Launch Claude Code
    1. Branch naming
  5. AI Tool Hooks
    1. How it works
    2. Installing hooks
    3. Check hook status
  6. Claude Code hooks
    1. Hook commands
    2. Behavior
    3. Configuration file
  7. Cursor hooks
    1. Hook commands
    2. Behavior
    3. Configuration file
  8. Environment variables
    1. Examples
    2. Default behavior
  9. Worktree locations
  10. Troubleshooting
    1. Hooks not firing
    2. Worktree not created
    3. Session not tracked

Installation

The CLI is bundled with Git Canopy. To install:

  1. Open Git Canopy
  2. Go to Git Canopy > Settings in the menu bar (not the project settings in the sidebar)
  3. Click Install CLI

This installs the canopy command to /usr/local/bin/canopy.

Shell integration

Add ~/.canopy/bin to your PATH by adding this to your shell config:

# For zsh (add to ~/.zshrc)
eval "$(canopy shell-init zsh)"

# For bash (add to ~/.bashrc)
eval "$(canopy shell-init bash)"

# For fish (add to ~/.config/fish/config.fish)
canopy shell-init fish | source

Commands

canopy add

Create a new worktree. Idempotent - returns existing path if the branch already has a worktree.

# Create worktree with auto-generated branch name
canopy add

# Create worktree for specific branch
canopy add feature-login

# Create from a specific base branch
canopy add feature-login --base develop

canopy list

List all worktrees in the current repository.

canopy list
canopy ls  # alias

# Output as JSON
canopy list --json

# Include commit hashes
canopy list --verbose

canopy status

Show the status of the current worktree.

canopy status

# Output as JSON
canopy status --json

canopy reload

Trigger a reload of local state in the Git Canopy GUI (fast, no network).

canopy reload

# Specify repository path
canopy reload --path /path/to/repo

canopy fetch

Fetch from remote and fully refresh the Git Canopy GUI.

canopy fetch

# Specify repository path
canopy fetch --path /path/to/repo

Launch Claude Code

The easiest way to use Git Canopy with Claude Code is the run command:

canopy claude run

This creates a new worktree for an isolated coding session, then launches Claude Code inside it. Any arguments after run are passed to Claude:

canopy claude run --resume    # Resume previous session
canopy claude run -p "fix the bug"  # Start with a prompt

If you’re already in a Git Canopy worktree, it launches Claude directly without creating a new one.

Branch naming

Branches start with a generated name like claude-a1b2c3d4. After your first prompt, Git Canopy automatically renames the branch based on what you asked for:

claude-a1b2c3d4  →  fix-auth-bug-a1b2c3

This makes it easy to identify sessions later.


AI Tool Hooks

Git Canopy can automatically create worktrees when you start coding sessions with Claude Code or Cursor. This keeps each AI conversation isolated on its own branch.

How it works

  1. You start a conversation in Claude Code or Cursor
  2. When the AI makes its first file edit, the hook creates a new worktree
  3. The AI is instructed to cd into the new worktree
  4. All subsequent edits happen in the isolated worktree

This prevents AI tools from accidentally modifying your main branch or mixing changes from different conversations.

Installing hooks

Install hooks for both Claude Code and Cursor:

# Install in current project only
canopy hooks install

# Install globally (all projects)
canopy hooks install --global

# Install for specific tool only
canopy hooks install --claude
canopy hooks install --cursor

Check hook status

canopy hooks status

This shows whether hooks are installed and where.


Claude Code hooks

The Claude Code integration uses the PreToolUse hook to intercept file edits before they happen.

Hook commands

canopy claude pre-tool   # PreToolUse hook - creates worktree on first edit
canopy claude stop       # Stop hook - marks session as completed

Behavior

When Claude Code calls Write, Edit, or Bash tools:

  1. First edit from main repo: Creates a new worktree, blocks the edit, and instructs Claude to cd to the worktree first
  2. First edit from existing worktree: Tracks the session against that worktree without creating a new one
  3. Subsequent edits: Updates session activity tracking

Configuration file

Hooks are configured in .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit|Bash",
        "hooks": [
          {
            "type": "command",
            "command": "canopy claude pre-tool"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "canopy claude stop"
          }
        ]
      }
    ]
  }
}

Cursor hooks

The Cursor integration uses the afterFileEdit hook to create worktrees after the first edit.

Hook commands

canopy cursor after-edit  # afterFileEdit hook - creates worktree on first edit
canopy cursor stop        # Stop hook - marks session as completed

Behavior

When Cursor edits a file:

  1. First edit from main repo: Creates a new worktree and instructs Cursor to cd to it
  2. First edit from existing worktree: Tracks the session against that worktree
  3. Subsequent edits: Updates session activity and file count

Configuration file

Hooks are configured in .cursor/hooks.json:

{
  "version": 1,
  "hooks": {
    "afterFileEdit": [
      {
        "command": "canopy cursor after-edit"
      }
    ],
    "stop": [
      {
        "command": "canopy cursor stop"
      }
    ]
  }
}

Environment variables

These environment variables control hook behavior:

Variable Effect
CANOPY_SKIP_WORKTREE Skip worktree creation entirely. Sessions are still tracked, but no new worktrees are created.
CANOPY_FORCE_NEW_WORKTREE Always create a new worktree, even when already in one.

Examples

Skip worktree creation for a session:

CANOPY_SKIP_WORKTREE=1 claude

Force a new worktree even when in an existing one:

CANOPY_FORCE_NEW_WORKTREE=1 claude

Default behavior

Without either variable set:

Starting location Result
Main repository Creates new worktree
Existing worktree Uses existing worktree (no new one created)

Worktree locations

Worktrees created by hooks are placed in:

~/.canopy/worktrees/<repo-name>/<branch-name>/

For example, a Claude Code session in the git-canopy repo might create:

~/.canopy/worktrees/git-canopy/claude-a1b2c3d4/

Troubleshooting

Hooks not firing

  1. Check hooks are installed: canopy hooks status
  2. Verify the config file exists (.claude/settings.json or .cursor/hooks.json)
  3. Check the canopy command is in your PATH

Worktree not created

Check the logs at ~/.canopy/logs/hooks.log for errors.

Common issues:

  • Not in a git repository
  • Branch name conflicts
  • Disk space issues

Session not tracked

Ensure the AI tool is passing the required context (session ID, working directory) to the hook via stdin.


Back to top

Git Canopy — A Git worktree manager for macOS

This site uses Just the Docs, a documentation theme for Jekyll.