#!/bin/bash # git-worktree-ai - Create git worktrees and with linked AI agent configuration files # # Usage: # ./git-worktree-ai # git worktree-ai (when added as git alias) # # Examples: # ./git-worktree-ai ../feature-auth feature-auth # git worktree-ai ../bugfix-login bugfix-login set -e CONFIG_FILES=( # Claude Code "CLAUDE.local.md" "CLAUDE.md" ".claude" ".mcp.json" # VS Code config ".vscode" # Directory: entire .vscode folder # env files ".env*" ) if [ $# -lt 2 ]; then echo "Missing required argument". echo "Usage $0 " exit 1 fi WORKTREE_PATH="$1" BRANCH_NAME="$2" # Validate that we are in a git repo if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then echo "Not inside a git repository" exit 1 fi if [ -e "$WORKTREE_PATH" ]; then echo "Path $WORKTREE_PATH already exists" exit 1 fi # Check if branch already exists if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then echo "Branch $BRANCH_NAME already exists" exit 1 fi echo "Creating worktree $WORKTREE_PATH with new branch $BRANCH_NAME" if ! git worktree add "$WORKTREE_PATH" -b "$BRANCH_NAME"; then echo "Faild to create worktree" exit 1 else echo "Worktree created successfully" fi cd "$WORKTREE_PATH" # Find the main repository using git-common-dir echo "Finding main repository..." MAIN_REPO=$(dirname "$(git rev-parse --git-common-dir)") MAIN_REPO=$(cd "$MAIN_REPO" && pwd) # Get absolute path echo "Main repository at $MAIN_REPO" # Function to expand wildcards and return matching files/directories expand_pattern() { local pattern="$1" local base_dir="$2" # Change to base directory and use shell globbing ( cd "$base_dir" # Set nullglob so patterns with no matches expand to nothing shopt -s nullglob # Expand the pattern for match in $pattern; do echo "$match" done ) } for pattern in "${CONFIG_FILES[@]}"; do echo "$pattern" # Expand wildcards in the main repository matches=$(expand_pattern "$pattern" "$MAIN_REPO") # Process each match while IFS= read -r file; do # skip empty lines [ -z "$file" ] && continue SOURCE_PATH="$MAIN_REPO/$file" TARGET_PATH="$file" if [ -f "$SOURCE_PATH" ]; then # Handle files: create parent directory if needed PARENT_DIR="$(dirname "$TARGET_PATH")" if [ "$PARENT_DIR" != "." ]; then mkdir -p "$PARENT_DIR" fi ln -sf "$SOURCE_PATH" "$TARGET_PATH" echo "Linked file: $file" elif [ -d "$SOURCE_PATH" ]; then # Handle directories: create parent directory if needed, remove target if it exists PARENT_DIR="$(dirname "$TARGET_PATH")" if [ "$PARENT_DIR" != "." ]; then mkdir -p "$PARENT_DIR" fi # Remove target if it exists (could be empty dir created by mistake) if [ -e "$TARGET_PATH" ] && [ ! -L "$TARGET_PATH" ]; then rm -rf "$TARGET_PATH" fi ln -sf "$SOURCE_PATH" "$TARGET_PATH" echo "Linked directory: $file" else echo "Skipped $file. What is this?" fi done <<< "$matches" done