Repository: facebook/react
Pull request: Add worktree script

Intended to be used directly and/or from skills in an agent.

Usage is `./scripts/worktree.sh [--compiler] [--claude] <name>`. The script:
* Checks that ./worktrees is in gitignore
* Checks the named worktree does not exist yet
* Creates the named worktree in ./worktrees/
* Installs deps
* cds into the worktree (optionally the compiler dir if `--compiler`)
* optionally runs claude in the worktree if `--claude`



Changed files:
filename: .gitignore
patch: @@ -24,6 +24,7 @@ chrome-user-data
 *.swp
 *.swo
 /tmp
+/worktrees
 
 packages/react-devtools-core/dist
 packages/react-devtools-extensions/chrome/build

filename: scripts/worktree.sh
patch: @@ -0,0 +1,125 @@
+#!/usr/bin/env bash
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+#
+# This source code is licensed under the MIT license found in the
+# LICENSE file in the root directory of this source tree.
+
+set -eo pipefail
+
+# --- Configuration ---
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+WORKTREE_CREATED=false
+WORKTREE_PATH=""
+
+# --- Usage ---
+usage() {
+  echo "Usage: $0 <name> [--claude] [--compiler]"
+  echo ""
+  echo "Creates a new git worktree with dependencies installed."
+  echo ""
+  echo "Arguments:"
+  echo "  <name>        Name for the worktree (also used as branch name)"
+  echo ""
+  echo "Options:"
+  echo "  --claude      Launch Claude Code after setup"
+  echo "  --compiler    When used with --claude, launch Claude in the compiler directory"
+  exit 1
+}
+
+# --- Error handling ---
+error() {
+  echo "Error: $1" >&2
+  exit 1
+}
+
+# --- Cleanup on error ---
+cleanup() {
+  if [[ "$WORKTREE_CREATED" == "true" && -n "$WORKTREE_PATH" ]]; then
+    echo "Cleaning up: removing worktree at $WORKTREE_PATH..." >&2
+    git worktree remove "$WORKTREE_PATH" --force 2>/dev/null || true
+  fi
+}
+
+trap cleanup ERR
+
+# --- Argument parsing ---
+NAME=""
+USE_CLAUDE=false
+USE_COMPILER=false
+
+while [[ $# -gt 0 ]]; do
+  case "$1" in
+    --claude)
+      USE_CLAUDE=true
+      shift
+      ;;
+    --compiler)
+      USE_COMPILER=true
+      shift
+      ;;
+    -h|--help)
+      usage
+      ;;
+    -*)
+      error "Unknown option: $1"
+      ;;
+    *)
+      if [[ -z "$NAME" ]]; then
+        NAME="$1"
+      else
+        error "Unexpected argument: $1"
+      fi
+      shift
+      ;;
+  esac
+done
+
+if [[ -z "$NAME" ]]; then
+  usage
+fi
+
+# --- Check .gitignore ---
+if ! grep -qE '^/?worktrees/?$' "$REPO_ROOT/.gitignore" 2>/dev/null; then
+  error "'worktrees' is not in .gitignore. Add it before creating worktrees."
+fi
+
+# --- Check if worktree already exists ---
+if git worktree list | grep -q "\[$NAME\]"; then
+  error "Worktree with branch name '$NAME' already exists"
+fi
+
+# --- Set up worktree path ---
+WORKTREES_DIR="$REPO_ROOT/worktrees"
+WORKTREE_PATH="$WORKTREES_DIR/$NAME"
+
+if [[ -d "$WORKTREE_PATH" ]]; then
+  error "Directory already exists at $WORKTREE_PATH"
+fi
+
+# --- Create worktree ---
+mkdir -p "$WORKTREES_DIR"
+echo "Creating worktree '$NAME' at $WORKTREE_PATH..."
+git worktree add "$WORKTREE_PATH" -b "$NAME"
+WORKTREE_CREATED=true
+
+# --- Install dependencies ---
+echo "Installing compiler dependencies..."
+(cd "$WORKTREE_PATH/compiler" && yarn install)
+
+echo "Installing root dependencies..."
+(cd "$WORKTREE_PATH" && yarn install)
+
+echo "Worktree '$NAME' created successfully at $WORKTREE_PATH"
+
+# --- Launch Claude (optional) ---
+if [[ "$USE_CLAUDE" == "true" ]]; then
+  if [[ "$USE_COMPILER" == "true" ]]; then
+    echo "Launching Claude in compiler directory..."
+    cd "$WORKTREE_PATH/compiler"
+  else
+    echo "Launching Claude in worktree root..."
+    cd "$WORKTREE_PATH"
+  fi
+  exec claude
+fi