Skip to content

Instantly share code, notes, and snippets.

@reagent
Last active January 29, 2026 17:20
Show Gist options
  • Select an option

  • Save reagent/a33e0c098f8f2229ce6a3b265f876a4d to your computer and use it in GitHub Desktop.

Select an option

Save reagent/a33e0c098f8f2229ce6a3b265f876a4d to your computer and use it in GitHub Desktop.
#!/bin/bash
# Git subcommand to add a worktree and copy configured files
# Usage: git worktree-copy <path> [<commit-ish>] [<other-options>]
# Configuration: .worktree-copy in repo root
# - One file/directory per line to copy
# - Lines starting with ! are executed as commands in the new worktree
# - Lines starting with # are comments
set -e
# Check if at least one argument is provided
if [ $# -lt 1 ]; then
echo "Usage: git worktree-copy <path> [<commit-ish>] [<other-options>]"
echo "Example: git worktree-copy ../feature-branch feature-branch"
exit 1
fi
# Get the source directory (current git repo root)
SOURCE_DIR=$(git rev-parse --show-toplevel)
# Configuration file
CONFIG_FILE="$SOURCE_DIR/.worktree-copy"
# First argument is the worktree path
WORKTREE_PATH="$1"
# Run git worktree add with all provided arguments
echo "Creating worktree at: $WORKTREE_PATH"
git worktree add "$@"
# Resolve the absolute path of the new worktree
WORKTREE_ABS_PATH=$(cd "$WORKTREE_PATH" && pwd)
# Check if config file exists
if [ ! -f "$CONFIG_FILE" ]; then
echo "Warning: $CONFIG_FILE not found. No files will be copied."
echo "Create a .worktree-copy file in your repo root with one file/directory per line."
exit 0
fi
# Read config file and copy each entry
echo "Copying files from $CONFIG_FILE..."
while IFS= read -r line || [ -n "$line" ]; do
# Skip empty lines and comments
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
# Trim whitespace
item=$(echo "$line" | xargs)
# Check if this is a command (starts with !)
if [[ "$item" =~ ^! ]]; then
cmd="${item#!}"
cmd=$(echo "$cmd" | xargs) # Trim whitespace after !
echo " Running: $cmd"
(cd "$WORKTREE_ABS_PATH" && eval "$cmd")
continue
fi
SOURCE_PATH="$SOURCE_DIR/$item"
if [ -d "$SOURCE_PATH" ]; then
echo " Copying directory: $item"
cp -r "$SOURCE_PATH" "$WORKTREE_ABS_PATH/"
elif [ -f "$SOURCE_PATH" ]; then
echo " Copying file: $item"
cp "$SOURCE_PATH" "$WORKTREE_ABS_PATH/"
else
echo " Warning: $item not found, skipping"
fi
done < "$CONFIG_FILE"
echo "✓ Worktree created and files copied successfully!"
echo " Location: $WORKTREE_ABS_PATH"
@reagent
Copy link
Author

reagent commented Jan 22, 2026

Add to your global ~/.gitconfig:

[alias]
  worktree-copy = \\!~/.local/bin/git-worktree-copy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment