Skip to content

Instantly share code, notes, and snippets.

@cpoile
Last active July 9, 2025 15:31
Show Gist options
  • Select an option

  • Save cpoile/550e7a83745537a2aeee5bb674bb75d0 to your computer and use it in GitHub Desktop.

Select an option

Save cpoile/550e7a83745537a2aeee5bb674bb75d0 to your computer and use it in GitHub Desktop.
Easy git worktree setup for mattermost / enterprise directories
#!/bin/bash
set -e
#
# Configuration - change these if your directories have different names
SERVER_DIR_NAME="server"
ENTERPRISE_DIR_NAME="enterprise"
# List of additional files to copy to server worktree
server_files=(
"webapp/.dir-locals.el:webapp/.dir-locals.el"
"config/config.json:config/config.json"
"docker-compose.override.yaml:docker-compose.override.yaml"
"server/config.override.mk:server/config.override.mk"
# Add more files here in format "source:destination"
# "sub-dir/other-file.txt:sub-dir/other-file.txt"
)
# List of additional files to copy to enterprise worktree
enterprise_files=(
# Add files here in format "source:destination"
# "sub-dir/other-file.txt:sub-dir/other-file.txt"
)
# Get current directory name to use as base name
BASENAME=$(basename "$(pwd)")
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to show usage
usage() {
echo "Usage: $0 <command> [arguments]"
echo ""
echo "Commands:"
echo " create <branch-name> <short-name> Create worktrees for branch with short directory name"
echo " remove <branch-name> [--force] Remove worktrees and worktree base directory"
echo " list List existing worktree directories"
echo ""
echo "Examples:"
echo " $0 create MM-63556-compliance-export-download compliance-export"
echo " $0 remove MM-63556-compliance-export-download"
echo " $0 remove MM-63556-compliance-export-download --force"
echo " $0 list"
echo ""
echo "Create will make:"
echo " - $BASENAME-compliance-export/"
echo " ├── CLAUDE.md, CLAUDE.local.md, etc. (copied from current base dir)"
echo " ├── $SERVER_DIR_NAME/ (git worktree for MM-63556-compliance-export-download branch)"
echo " └── $ENTERPRISE_DIR_NAME/ (git worktree for MM-63556-compliance-export-download branch)"
exit 1
}
# Check for help flags
if [ "$1" = "--help" ] || [ "$1" = "-h" ] || [ "$1" = "help" ]; then
usage
fi
# Parse command and arguments
if [ $# -eq 0 ]; then
print_error "Command is required"
usage
fi
COMMAND="$1"
BRANCH_NAME=""
# Validate command
if [ "$COMMAND" != "create" ] && [ "$COMMAND" != "remove" ] && [ "$COMMAND" != "list" ]; then
print_error "Invalid command: $COMMAND"
print_error "Valid commands: create, remove, list"
usage
fi
# Check arguments for commands
FORCE_MODE=false
BRANCH_NAME=""
SHORT_NAME=""
if [ "$COMMAND" = "create" ]; then
# Create command needs: create <branch-name> <short-name>
if [ $# -ne 3 ]; then
print_error "Create command requires both branch-name and short-name"
print_error "Usage: $0 create <branch-name> <short-name>"
usage
fi
BRANCH_NAME="$2"
SHORT_NAME="$3"
elif [ "$COMMAND" = "remove" ]; then
# Remove command: remove <branch-name> [--force]
if [ $# -eq 3 ] && [ "$3" = "--force" ]; then
FORCE_MODE=true
BRANCH_NAME="$2"
elif [ $# -eq 3 ] && [ "$2" = "--force" ]; then
FORCE_MODE=true
BRANCH_NAME="$3"
elif [ $# -eq 2 ]; then
BRANCH_NAME="$2"
else
print_error "Remove command requires branch-name"
print_error "Usage: $0 remove <branch-name> [--force]"
usage
fi
elif [ "$COMMAND" = "list" ]; then
# List command takes no additional arguments
if [ $# -ne 1 ]; then
print_error "List command takes no arguments"
usage
fi
fi
# Validate names for create/remove commands
if [ "$COMMAND" = "create" ]; then
if [[ ! "$BRANCH_NAME" =~ ^[a-zA-Z0-9_\.-]+$ ]]; then
print_error "Invalid branch name. Use only letters, numbers, hyphens, periods, and underscores."
exit 1
fi
if [[ ! "$SHORT_NAME" =~ ^[a-zA-Z0-9_\.-]+$ ]]; then
print_error "Invalid short name. Use only letters, numbers, hyphens, periods, and underscores."
exit 1
fi
elif [ "$COMMAND" = "remove" ]; then
if [[ ! "$BRANCH_NAME" =~ ^[a-zA-Z0-9_\.-]+$ ]]; then
print_error "Invalid branch name. Use only letters, numbers, hyphens, periods, and underscores."
exit 1
fi
fi
# Function to list existing worktree directories
list_worktrees() {
local parent_dir=$(dirname "$CURRENT_DIR")
local found=false
print_status "Existing worktree directories:"
for dir in "$parent_dir"/$BASENAME-*; do
if [ -d "$dir" ]; then
local short_name=$(basename "$dir" | sed "s/^$BASENAME-//")
local branch_info=""
# Try to get branch info from server worktree
if [ -d "$dir/$SERVER_DIR_NAME" ]; then
branch_info=$(cd "$dir/$SERVER_DIR_NAME" 2>/dev/null && git branch --show-current 2>/dev/null)
if [ -n "$branch_info" ]; then
echo " - $short_name (branch: $branch_info)"
else
echo " - $short_name (branch: unknown)"
fi
else
echo " - $short_name (invalid - no $SERVER_DIR_NAME directory)"
fi
found=true
fi
done
if [ "$found" = false ]; then
echo " No worktree directories found"
fi
}
# Function to remove worktrees and base directory
remove_worktree() {
local branch_name="$1"
local force_mode="$2"
local parent_dir=$(dirname "$CURRENT_DIR")
local base_dir=""
local server_worktree=""
local enterprise_worktree=""
print_status "Searching for worktrees with branch: $branch_name"
# Find the base directory that contains this branch
local found=false
for dir in "$parent_dir"/$BASENAME-*; do
if [ -d "$dir/$SERVER_DIR_NAME" ]; then
local current_branch=$(cd "$dir/$SERVER_DIR_NAME" 2>/dev/null && git branch --show-current 2>/dev/null)
if [ "$current_branch" = "$branch_name" ]; then
base_dir="$dir"
server_worktree="$dir/$SERVER_DIR_NAME"
enterprise_worktree="$dir/$ENTERPRISE_DIR_NAME"
found=true
break
fi
fi
done
if [ "$found" = false ]; then
print_error "No worktree found for branch: $branch_name"
exit 1
fi
print_status "Found base directory: $base_dir"
# Show what will be removed
echo ""
print_warning "This will remove the following:"
echo " - Git worktree: $server_worktree"
echo " - Git worktree: $enterprise_worktree"
echo " - Entire directory: $base_dir"
echo ""
# Confirmation prompt (unless force mode)
if [ "$force_mode" = false ]; then
print_warning "Are you sure you want to remove these worktrees and directory? [y/N]"
read -r response
case "$response" in
[yY]|[yY][eE][sS])
print_status "Proceeding with removal..."
;;
*)
print_status "Removal cancelled."
exit 0
;;
esac
else
print_status "Force mode enabled - skipping confirmation."
fi
# Remove server worktree
if [ -d "$server_worktree" ]; then
print_status "Removing server worktree: $server_worktree"
(cd "$SERVER_DIR_NAME" && git worktree remove --force "$server_worktree" || true)
fi
# Remove enterprise worktree
if [ -d "$enterprise_worktree" ]; then
print_status "Removing enterprise worktree: $enterprise_worktree"
(cd "$ENTERPRISE_DIR_NAME" && git worktree remove --force "$enterprise_worktree" || true)
fi
# Remove the entire base directory
print_status "Removing base directory: $base_dir"
rm -rf "$base_dir"
print_status "Successfully removed worktrees and directory for branch: $branch_name"
}
# Get current directory and validate structure
CURRENT_DIR=$(pwd)
CURRENT_BASENAME=$(basename "$CURRENT_DIR")
# Validate that server and enterprise directories exist and are git repos
if [ ! -d "$SERVER_DIR_NAME" ]; then
print_error "$SERVER_DIR_NAME directory not found in current directory"
exit 1
fi
if [ ! -d "$ENTERPRISE_DIR_NAME" ]; then
print_error "$ENTERPRISE_DIR_NAME directory not found in current directory"
exit 1
fi
if [ ! -d "$SERVER_DIR_NAME/.git" ]; then
print_error "$SERVER_DIR_NAME directory is not a git repository"
exit 1
fi
if [ ! -d "$ENTERPRISE_DIR_NAME/.git" ]; then
print_error "$ENTERPRISE_DIR_NAME directory is not a git repository"
exit 1
fi
# Command dispatcher
case "$COMMAND" in
"list")
list_worktrees
exit 0
;;
"remove")
remove_worktree "$BRANCH_NAME" "$FORCE_MODE"
exit 0
;;
"create")
# Continue with create logic below
;;
*)
print_error "Unknown command: $COMMAND"
usage
;;
esac
# Create command logic starts here
# Get parent directory (where we'll create the new base directory)
PARENT_DIR=$(dirname "$CURRENT_DIR")
NEW_BASE_DIR="$PARENT_DIR/$BASENAME-$SHORT_NAME"
SERVER_WORKTREE_DIR="$NEW_BASE_DIR/$SERVER_DIR_NAME"
ENTERPRISE_WORKTREE_DIR="$NEW_BASE_DIR/$ENTERPRISE_DIR_NAME"
print_status "Branch name: $BRANCH_NAME"
print_status "Short name: $SHORT_NAME"
print_status "New base directory: $NEW_BASE_DIR"
print_status "Server worktree: $SERVER_WORKTREE_DIR"
print_status "Enterprise worktree: $ENTERPRISE_WORKTREE_DIR"
# Check if new base directory already exists
if [ -d "$NEW_BASE_DIR" ]; then
print_error "Directory already exists: $NEW_BASE_DIR"
exit 1
fi
# Create the new base directory
print_status "Creating new base directory: $NEW_BASE_DIR"
mkdir -p "$NEW_BASE_DIR"
# Function to cleanup on error
cleanup() {
print_error "Cleaning up due to error..."
if [ -d "$NEW_BASE_DIR" ]; then
rm -rf "$NEW_BASE_DIR"
print_status "Cleaned up: $NEW_BASE_DIR"
fi
cd "$CURRENT_DIR"
cd "$SERVER_DIR_NAME"
git worktree prune
cd "$CURRENT_DIR"
cd "$ENTERPRISE_DIR_NAME"
git worktree prune
}
# Set trap for cleanup on error
trap cleanup ERR
# Copy all files and directories from current base dir (except server and enterprise)
print_status "Copying base files (excluding server and enterprise directories)..."
for item in * .*; do
# Skip . and .. and server and enterprise directories
if [ "$item" = "." ] || [ "$item" = ".." ] || [ "$item" = "$SERVER_DIR_NAME" ] || [ "$item" = "$ENTERPRISE_DIR_NAME" ]; then
continue
fi
# Skip if item doesn't exist (handles glob expansion issues)
if [ ! -e "$item" ]; then
continue
fi
print_status "Copying: $item"
cp -r "$item" "$NEW_BASE_DIR/"
done
# Check if branch exists in server repo, create if it doesn't
print_status "Checking $SERVER_DIR_NAME repository for branch: $BRANCH_NAME"
cd "$SERVER_DIR_NAME"
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
print_status "Branch $BRANCH_NAME already exists in $SERVER_DIR_NAME repo"
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
print_status "Branch $BRANCH_NAME exists on remote, will create local tracking branch"
else
print_warning "Branch $BRANCH_NAME does not exist in $SERVER_DIR_NAME repo, will create new branch"
fi
# Create server worktree
print_status "Creating server worktree: $SERVER_WORKTREE_DIR"
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
# Branch exists locally
git worktree add "$SERVER_WORKTREE_DIR" "$BRANCH_NAME"
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
# Branch exists on remote, create local tracking branch
git worktree add -b "$BRANCH_NAME" "$SERVER_WORKTREE_DIR" "origin/$BRANCH_NAME"
else
# Create new branch
git worktree add -b "$BRANCH_NAME" "$SERVER_WORKTREE_DIR"
fi
# Go back to base directory
cd "$CURRENT_DIR"
# Check if branch exists in enterprise repo, create if it doesn't
print_status "Checking $ENTERPRISE_DIR_NAME repository for branch: $BRANCH_NAME"
cd "$ENTERPRISE_DIR_NAME"
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
print_status "Branch $BRANCH_NAME already exists in $ENTERPRISE_DIR_NAME repo"
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
print_status "Branch $BRANCH_NAME exists on remote, will create local tracking branch"
else
print_warning "Branch $BRANCH_NAME does not exist in $ENTERPRISE_DIR_NAME repo, will create new branch"
fi
# Create enterprise worktree
print_status "Creating enterprise worktree: $ENTERPRISE_WORKTREE_DIR"
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
# Branch exists locally
git worktree add "$ENTERPRISE_WORKTREE_DIR" "$BRANCH_NAME"
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
# Branch exists on remote, create local tracking branch
git worktree add -b "$BRANCH_NAME" "$ENTERPRISE_WORKTREE_DIR" "origin/$BRANCH_NAME"
else
# Create new branch
git worktree add -b "$BRANCH_NAME" "$ENTERPRISE_WORKTREE_DIR"
fi
# Go back to base directory
cd "$CURRENT_DIR"
# Copy go work files
print_status "Copying go.work files and others..."
# Copy go.work* from $SERVER_DIR_NAME/servre to new $SERVER_DIR_NAME/server
for gowork_file in "$SERVER_DIR_NAME/server"/go.work*; do
if [ -f "$gowork_file" ]; then
print_status "Copying $(basename "$gowork_file") from $SERVER_DIR_NAME/server to new $SERVER_DIR_NAME/server"
mkdir -p "$SERVER_WORKTREE_DIR/server"
cp "$gowork_file" "$SERVER_WORKTREE_DIR/server/"
fi
done
for file_mapping in "${server_files[@]}"; do
source_file="$SERVER_DIR_NAME/${file_mapping%%:*}"
dest_file="${file_mapping##*:}"
if [ -f "$source_file" ]; then
print_status "Copying $(basename "$source_file") to server worktree"
mkdir -p "$(dirname "$SERVER_WORKTREE_DIR/$dest_file")"
cp "$source_file" "$SERVER_WORKTREE_DIR/$dest_file"
fi
done
# Copy go.work* from $ENTERPRISE_DIR_NAME to new $ENTERPRISE_DIR_NAME
for gowork_file in "$ENTERPRISE_DIR_NAME"/go.work*; do
if [ -f "$gowork_file" ]; then
print_status "Copying $(basename "$gowork_file") from $ENTERPRISE_DIR_NAME to new $ENTERPRISE_DIR_NAME"
cp "$gowork_file" "$ENTERPRISE_WORKTREE_DIR/"
fi
done
for file_mapping in "${enterprise_files[@]}"; do
source_file="$ENTERPRISE_DIR_NAME/${file_mapping%%:*}"
dest_file="${file_mapping##*:}"
if [ -f "$source_file" ]; then
print_status "Copying $(basename "$source_file") to enterprise worktree"
mkdir -p "$(dirname "$ENTERPRISE_WORKTREE_DIR/$dest_file")"
cp "$source_file" "$ENTERPRISE_WORKTREE_DIR/$dest_file"
fi
done
# Remove trap since we succeeded
trap - ERR
print_status "Successfully created worktrees and copied base files!"
echo ""
print_status "Directory structure:"
echo " $NEW_BASE_DIR/"
echo " ├── CLAUDE.md, CLAUDE.local.md, mise.toml, etc. (copied files)"
echo " ├── $(basename "$SERVER_WORKTREE_DIR")/ (git worktree)"
echo " └── $(basename "$ENTERPRISE_WORKTREE_DIR")/ (git worktree)"
echo ""
print_status "To remove these worktrees later, use:"
echo " ./worktree remove $BRANCH_NAME"
#!/bin/bash
# Working completion for worktree script with subcommands
# Get directory names from the main worktree script
get_server_dir_name() {
if [ -f "./worktree" ]; then
grep '^SERVER_DIR_NAME=' "./worktree" 2>/dev/null | cut -d'=' -f2 | tr -d '"'
else
echo "server" # fallback default
fi
}
get_enterprise_dir_name() {
if [ -f "./worktree" ]; then
grep '^ENTERPRISE_DIR_NAME=' "./worktree" 2>/dev/null | cut -d'=' -f2 | tr -d '"'
else
echo "enterprise" # fallback default
fi
}
SERVER_DIR_NAME=$(get_server_dir_name)
ENTERPRISE_DIR_NAME=$(get_enterprise_dir_name)
BASENAME=$(basename "$(pwd)")
# Get available branches from server repo
_worktree_branches() {
if [ -d "$SERVER_DIR_NAME/.git" ]; then
(cd "$SERVER_DIR_NAME" 2>/dev/null && {
git branch --format='%(refname:short)' 2>/dev/null | grep -v '^master$' | grep -v '^main$'
git branch -r --format='%(refname:short)' 2>/dev/null | sed 's|origin/||' | grep -v HEAD | grep -v '^master$' | grep -v '^main$'
} | sort -u 2>/dev/null)
fi
}
# Get existing worktree branch names
_worktree_existing_branches() {
local parent_dir=$(dirname "$(pwd)")
local branches=""
# We can run from any directory that has server and enterprise subdirs
if [ ! -d "$SERVER_DIR_NAME" ] || [ ! -d "$ENTERPRISE_DIR_NAME" ]; then
return
fi
for dir in "$parent_dir"/$BASENAME-*; do
# Skip if directory doesn't exist or is a file
if [ ! -d "$dir" ]; then
continue
fi
# Check if it has a server directory with git (worktrees have .git file, not directory)
if [ -d "$dir/$SERVER_DIR_NAME" ] && ([ -d "$dir/$SERVER_DIR_NAME/.git" ] || [ -f "$dir/$SERVER_DIR_NAME/.git" ]); then
local branch=$(cd "$dir/$SERVER_DIR_NAME" 2>/dev/null && git branch --show-current 2>/dev/null)
if [ -n "$branch" ]; then
echo "$branch"
fi
fi
done | sort -u
}
# Zsh completion using compctl
if [ -n "$ZSH_VERSION" ]; then
# Completion function that handles commands and arguments
_worktree_complete() {
local words=("${(@s/ /)BUFFER}")
local current_word="${words[-1]}"
local prev_word="${words[-2]:-}"
local word_count=${#words[@]}
# If we're completing the first argument
if [ $word_count -eq 2 ] || ([ $word_count -eq 1 ] && [ -z "$current_word" ]); then
# Complete with commands only
local commands="create remove list"
reply=(${(s/ /)commands})
elif [ $word_count -eq 3 ] || ([ $word_count -eq 2 ] && [ -n "$current_word" ]); then
# Complete second argument based on first argument
case "$prev_word" in
"create")
# Complete with available branches for first argument
reply=(${(f)"$(_worktree_branches)"})
;;
"remove")
# Complete with existing branch names
reply=(${(f)"$(_worktree_existing_branches)"})
;;
"list")
# No completion needed for list
reply=()
;;
*)
# No additional completion
reply=()
;;
esac
elif [ $word_count -eq 4 ] || ([ $word_count -eq 3 ] && [ -n "$current_word" ]); then
# Complete third argument (only for create command - short name)
local first_cmd="${words[1]}"
if [ "$first_cmd" = "create" ]; then
# For create command, third argument is short-name - no completion
reply=()
else
reply=()
fi
else
reply=()
fi
}
# Use compctl for completion
compctl -K _worktree_complete worktree
compctl -K _worktree_complete ./worktree
echo "Zsh completion loaded for worktree with subcommands"
fi
# Bash completion
if [ -n "$BASH_VERSION" ]; then
_worktree_bash_complete() {
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local word_count=${#COMP_WORDS[@]}
# Complete first argument
if [ $COMP_CWORD -eq 1 ]; then
local commands="create remove list"
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
# Complete second argument based on first
elif [ $COMP_CWORD -eq 2 ]; then
case "$prev" in
"create")
local branches=$(_worktree_branches)
COMPREPLY=($(compgen -W "$branches" -- "$cur"))
;;
"remove")
local existing=$(_worktree_existing_branches)
COMPREPLY=($(compgen -W "$existing" -- "$cur"))
;;
"list")
COMPREPLY=()
;;
*)
COMPREPLY=()
;;
esac
# Complete third argument (short-name for create command)
elif [ $COMP_CWORD -eq 3 ]; then
# Only create command has a third argument
if [ "${COMP_WORDS[1]}" = "create" ]; then
# Short name - no completion suggestions
COMPREPLY=()
else
COMPREPLY=()
fi
else
COMPREPLY=()
fi
}
complete -F _worktree_bash_complete worktree
complete -F _worktree_bash_complete ./worktree
echo "Bash completion loaded for worktree with subcommands"
fi

Worktree Script Setup

This directory contains a worktree script that creates git worktrees for both server and enterprise repositories in a new base directory structure, and copies all the base files (except server and enterprise directories) to the new location.

Configuration

The script is configurable for different directory naming conventions. At the top of the worktree script, you can modify:

# Configuration - change these if your directories have different names
SERVER_DIR_NAME="server"
ENTERPRISE_DIR_NAME="enterprise"

For example, if your directories are named differently:

SERVER_DIR_NAME="mattermost"
ENTERPRISE_DIR_NAME="mattermost-enterprise"

The script automatically uses the current directory name as the base name for creating new worktree directories. If you're in a directory called "my-project", it will create "my-project-shortname" directories.

You can also add any files you need copied over to the server_files and enterprise_files lists.

Usage

./worktree <command> [arguments]

Commands

  • create - Create worktrees and copy files with custom directory name
  • remove - Remove worktrees and base directory (with confirmation)
  • list - List existing worktree directories

Examples

# Create worktrees with short directory name
./worktree create MM-63556-compliance-export-download compliance-export

# List existing worktrees (shows both short name and branch)
./worktree list

# Remove worktrees by branch name (with confirmation prompt)
./worktree remove MM-63556-compliance-export-download

# Remove worktrees without confirmation (for scripts)
./worktree remove MM-63556-compliance-export-download --force

Create Command Result

monorepo-compliance-export/
├── CLAUDE.md                                         (copied from current base dir)
├── CLAUDE.local.md                                   (copied from current base dir)
├── mise.toml                                         (copied from current base dir)
├── ... (all other files/dirs except server/enterprise)
├── server/                                           (git worktree for MM-63556-compliance-export-download)
└── enterprise/                                       (git worktree for MM-63556-compliance-export-download)

Shell Completion Setup

To enable tab completion for branch names:

Option 1: Source the completion script for current session

source ./worktree-completion-working.bash

Option 2: Add to your shell profile for permanent setup

Add this line to your ~/.bashrc, ~/.bash_profile, or ~/.zshrc:

source /wherever/worktree-completion-working.bash

After setup, you can use tab completion:

worktree <TAB>                    # Shows: create, remove, list
worktree create MM-<TAB>          # Shows available branches starting with MM-
worktree create MM-123 <TAB>      # Short name - no completion (type freely)
worktree remove <TAB>             # Shows existing branch names for removal

Cleanup Worktrees

Easy Way (Recommended)

# Interactive removal with confirmation (use branch name, not short name)
./worktree remove <branch-name>

# Force removal without confirmation (for scripts)
./worktree remove <branch-name> --force

Manual Way

cd server && git worktree remove ../BASE-NAME-SHORT-NAME/server
cd enterprise && git worktree remove ../BASE-NAME-SHORT-NAME/enterprise
rm -rf ../BASE-NAME-SHORT-NAME

The remove command automatically handles all cleanup including git worktree removal and directory deletion. It finds worktrees by branch name and shows what will be removed, asking for confirmation to prevent accidental deletions.

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