Git Worktree Setup banner
rtk-ai rtk-ai

Git Worktree Setup

Git community intermediate

Description

Create isolated git worktrees with instant feedback and background Rust verification. **Performance**: ~1s setup + background `cargo check` (non-blocking)

Installation

Terminal
claude install-skill https://github.com/rtk-ai/rtk

README


model: haiku description: Git Worktree Setup for RTK (Rust project) argument-hint: ""

Git Worktree Setup

Create isolated git worktrees with instant feedback and background Rust verification.

**Performance**: ~1s setup + background `cargo check` (non-blocking)

Usage

/worktree feature/new-filter       # Creates worktree + background cargo check
/worktree fix/typo --fast          # Skip cargo check (instant)
/worktree feature/big-refactor --check  # Wait for cargo check (blocking)

**Branch naming**: Always use `category/description` with a slash.

    undefined

Implementation

Execute this **single bash script** with branch name from `$ARGUMENTS`:

#!/bin/bash
set -euo pipefail

trap 'kill $(jobs -p) 2>/dev/null || true' EXIT

# Resolve main repo root (works from worktree too)
GIT_COMMON_DIR="$(git rev-parse --git-common-dir 2>/dev/null)"
if [ -z "$GIT_COMMON_DIR" ]; then
  echo "Not in a git repository"
  exit 1
fi
REPO_ROOT="$(cd "$GIT_COMMON_DIR/.." && pwd)"

# Parse flags
RAW_ARGS="$ARGUMENTS"
BRANCH_NAME="$RAW_ARGS"
SKIP_CHECK=false
BLOCKING_CHECK=false

if [[ "$RAW_ARGS" == *"--fast"* ]]; then
  SKIP_CHECK=true
  BRANCH_NAME="${BRANCH_NAME// --fast/}"
fi
if [[ "$RAW_ARGS" == *"--check"* ]]; then
  BLOCKING_CHECK=true
  BRANCH_NAME="${BRANCH_NAME// --check/}"
fi

# Validate branch name
if [[ "$BRANCH_NAME" =~ [[:space:]\$\`] ]]; then
  echo "Invalid branch name (spaces or special characters not allowed)"
  exit 1
fi
if [[ "$BRANCH_NAME" =~ [~^:?*\\\[\]] ]]; then
  echo "Invalid branch name (git forbidden characters)"
  exit 1
fi

# Paths
WORKTREE_NAME="${BRANCH_NAME//\//-}"
WORKTREE_DIR="$REPO_ROOT/.worktrees/$WORKTREE_NAME"
LOG_FILE="/tmp/worktree-cargocheck-${WORKTREE_NAME}.log"

# 1. Check .gitignore (fail-fast)
if ! grep -qE "^\.worktrees/?$" "$REPO_ROOT/.gitignore" 2>/dev/null; then
  echo ".worktrees/ not in .gitignore"
  echo "Run: echo '.worktrees/' >> .gitignore && git add .gitignore && git commit -m 'chore: ignore worktrees'"
  exit 1
fi

# 2. Create worktree
echo "Creating worktree for $BRANCH_NAME..."
mkdir -p "$REPO_ROOT/.worktrees"
if ! git worktree add "$WORKTREE_DIR" -b "$BRANCH_NAME" 2>/tmp/worktree-error.log; then
  echo "Failed to create worktree:"
  cat /tmp/worktree-error.log
  exit 1
fi

# 3. Copy files listed in .worktreeinclude (non-blocking)
(
  INCLUDE_FILE="$REPO_ROOT/.worktreeinclude"
  if [ -f "$INCLUDE_FILE" ]; then
    while IFS= read -r entry || [ -n "$entry" ]; do
      [[ "$entry" =~ ^#.*$ || -z "$entry" ]] && continue
      entry="$(echo "$entry" | xargs)"
      SRC="$REPO_ROOT/$entry"
      if [ -e "$SRC" ]; then
        DEST_DIR="$(dirname "$WORKTREE_DIR/$entry")"
        mkdir -p "$DEST_DIR"
        cp -R "$SRC" "$WORKTREE_DIR/$entry"
      fi
    done < "$INCLUDE_FILE"
  else
    cp "$REPO_ROOT"/.env