Created
July 8, 2025 09:17
-
-
Save davej/a43caf453bcba02ae56041f190a7601e to your computer and use it in GitHub Desktop.
`wtree` function to create and manage git worktrees
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Function to create and manage git worktrees | |
# 1. If the the current projects folder doesn't contain a subdirectory named "worktrees" then create it and add it to gitignore in the current project. | |
# 2. Create a git worktree and branch named feature-name (which was passed via the wtree alias argument) from the main project folder and save it inside the worktrees folder. | |
# 3. If there is a .env, prod.env or dev.env in the main project folder then copy it over to the worktrees folder. | |
# 4. Open the new feature-name worktree folder in a new window using Cursor. | |
wtree() { | |
# Check if a feature name was provided as an argument | |
if [ -z "$1" ]; then | |
# Print error message if no argument was provided | |
echo "Error: Please provide a feature name" | |
# Print usage instructions | |
echo "Usage: wtree <feature-name>" | |
# Exit with error code 1 | |
return 1 | |
fi | |
# Store the feature name from the first argument | |
local feature_name="$1" | |
# Check if we're in a git repository | |
if ! git rev-parse --git-dir > /dev/null 2>&1; then | |
# Print error message if not in a git repository | |
echo "Error: Not in a git repository" | |
# Exit with error code 1 | |
return 1 | |
fi | |
# Get the root directory of the git repository | |
local git_root=$(git rev-parse --show-toplevel) | |
# Define the worktrees directory path | |
local worktrees_dir="$git_root/worktrees" | |
# Check if the worktrees directory doesn't exist | |
if [ ! -d "$worktrees_dir" ]; then | |
# Create the worktrees directory | |
mkdir -p "$worktrees_dir" | |
# Print confirmation message | |
echo "Created worktrees directory at $worktrees_dir" | |
# Define the path to the .gitignore file | |
local gitignore_path="$git_root/.gitignore" | |
# Check if 'worktrees/' is already in .gitignore | |
if ! grep -q "^worktrees/$" "$gitignore_path" 2>/dev/null; then | |
# Add a newline before 'worktrees/' to ensure it's on its own line | |
echo -e "\nworktrees/" >> "$gitignore_path" | |
# Print confirmation message | |
echo "Added worktrees/ to .gitignore" | |
fi | |
fi | |
# Define the path for the new worktree | |
local worktree_path="$worktrees_dir/$feature_name" | |
# Check if a worktree with this name already exists | |
if [ -d "$worktree_path" ]; then | |
# Print error message if worktree already exists | |
echo "Error: Worktree '$feature_name' already exists" | |
# Exit with error code 1 | |
return 1 | |
fi | |
# Get the default branch name (could be main or master) | |
local default_branch=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@') | |
# If we couldn't determine the default branch, try common defaults | |
if [ -z "$default_branch" ]; then | |
# Check if 'main' branch exists | |
if git show-ref --verify --quiet refs/heads/main; then | |
# Set default branch to 'main' | |
default_branch="main" | |
# Check if 'master' branch exists | |
elif git show-ref --verify --quiet refs/heads/master; then | |
# Set default branch to 'master' | |
default_branch="master" | |
else | |
# Print error message if no default branch found | |
echo "Error: Could not determine default branch" | |
# Exit with error code 1 | |
return 1 | |
fi | |
fi | |
# Create the git worktree with a new branch based on the default branch | |
echo "Creating worktree '$feature_name' from branch '$default_branch'..." | |
# Execute git worktree add command with the new branch | |
git worktree add -b "$feature_name" "$worktree_path" "$default_branch" | |
# Check if the worktree creation was successful | |
if [ $? -ne 0 ]; then | |
# Print error message if worktree creation failed | |
echo "Error: Failed to create worktree" | |
# Exit with error code 1 | |
return 1 | |
fi | |
# Array of environment files to copy | |
local env_files=(".env" "prod.env" "dev.env") | |
# Loop through each environment file | |
for env_file in "${env_files[@]}"; do | |
# Define the source path for the environment file | |
local src_env="$git_root/$env_file" | |
# Check if the environment file exists in the main project | |
if [ -f "$src_env" ]; then | |
# Copy the environment file to the new worktree | |
cp "$src_env" "$worktree_path/$env_file" | |
# Print confirmation message | |
echo "Copied $env_file to worktree" | |
fi | |
done | |
# Check if Cursor is available in the system | |
if command -v cursor &> /dev/null; then | |
# Open the new worktree in Cursor | |
echo "Opening worktree in Cursor..." | |
# Execute cursor command with the worktree path | |
cursor "$worktree_path" | |
else | |
# Print warning if Cursor is not found | |
echo "Warning: Cursor command not found. Please open manually: $worktree_path" | |
fi | |
# Print success message | |
echo "Successfully created worktree '$feature_name' at $worktree_path" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment