Last active
January 22, 2026 18:52
-
-
Save NorfeldtKnowit/d269cd1861a885e63d36fc9062f8f42f to your computer and use it in GitHub Desktop.
Git worktree setup script with dependency syncing
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
| #!/bin/bash | |
| # Git Worktree Setup Script | |
| # Creates a new git worktree and optionally syncs dependencies from the main repo. | |
| # Useful for working on multiple branches simultaneously without re-installing dependencies. | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| # Configuration - override these with environment variables | |
| WORKTREE_BASE="${WORKTREE_BASE:-$HOME/repos/worktrees}" | |
| # Get the current repository path | |
| REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null) | |
| if [ -z "$REPO_PATH" ]; then | |
| echo -e "${RED}Error: Not in a git repository${NC}" | |
| exit 1 | |
| fi | |
| REPO_NAME=$(basename "$REPO_PATH") | |
| # Prompt for branch name | |
| echo -e "${BLUE}Enter branch name:${NC}" | |
| read -r BRANCH_NAME | |
| if [ -z "$BRANCH_NAME" ]; then | |
| echo -e "${RED}Error: Branch name cannot be empty${NC}" | |
| exit 1 | |
| fi | |
| # Create worktree directory if it doesn't exist | |
| mkdir -p "$WORKTREE_BASE" | |
| # Define worktree path | |
| WORKTREE_PATH="$WORKTREE_BASE/$REPO_NAME-$BRANCH_NAME" | |
| # Check if branch exists locally or remotely | |
| if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then | |
| echo -e "${YELLOW}Branch '$BRANCH_NAME' already exists locally${NC}" | |
| BRANCH_EXISTS=true | |
| elif git ls-remote --heads origin "$BRANCH_NAME" | grep -q "$BRANCH_NAME"; then | |
| echo -e "${YELLOW}Branch '$BRANCH_NAME' exists on remote${NC}" | |
| BRANCH_EXISTS=true | |
| else | |
| echo -e "${GREEN}Creating new branch '$BRANCH_NAME'${NC}" | |
| BRANCH_EXISTS=false | |
| fi | |
| # Create worktree | |
| echo -e "${BLUE}Creating worktree at: $WORKTREE_PATH${NC}" | |
| if [ "$BRANCH_EXISTS" = true ]; then | |
| git worktree add "$WORKTREE_PATH" "$BRANCH_NAME" 2>/dev/null || { | |
| # If it fails, try checking out from remote | |
| git worktree add "$WORKTREE_PATH" "origin/$BRANCH_NAME" -b "$BRANCH_NAME" 2>/dev/null || { | |
| echo -e "${RED}Error: Failed to create worktree${NC}" | |
| exit 1 | |
| } | |
| } | |
| else | |
| # Create new branch from current HEAD | |
| git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" || { | |
| echo -e "${RED}Error: Failed to create worktree${NC}" | |
| exit 1 | |
| } | |
| fi | |
| echo -e "${GREEN}Worktree created successfully${NC}" | |
| # Sync all files including dependencies from main repo | |
| echo -e "${BLUE}Syncing all files and dependencies from main repo...${NC}" | |
| # Perform rsync - quiet mode with overall stats at the end | |
| # This copies node_modules, vendor, build artifacts, etc. so you don't need to reinstall | |
| rsync -a --stats \ | |
| --exclude='.git' \ | |
| --exclude='*.log' \ | |
| --exclude='.DS_Store' \ | |
| "$REPO_PATH/" "$WORKTREE_PATH/" | tail -n 20 | |
| echo -e "${GREEN}All files and dependencies synced successfully!${NC}" | |
| echo -e "${YELLOW}You can start working immediately - all dependencies are ready.${NC}" | |
| echo -e "${GREEN}Setup complete!${NC}" | |
| echo -e "${BLUE}Worktree created at: $WORKTREE_PATH${NC}" | |
| echo "" | |
| # Check for available tools | |
| ALACRITTY_CMD="" | |
| HAS_ZELLIJ=false | |
| # Check for patched Alacritty first, then standard | |
| if [ -x "/Applications/Alacritty-Patched.app/Contents/MacOS/alacritty" ]; then | |
| ALACRITTY_CMD="/Applications/Alacritty-Patched.app/Contents/MacOS/alacritty" | |
| echo -e "${GREEN}Found: Alacritty (patched)${NC}" | |
| elif command -v alacritty &> /dev/null; then | |
| ALACRITTY_CMD="alacritty" | |
| echo -e "${GREEN}Found: Alacritty (standard)${NC}" | |
| fi | |
| # Check for zellij | |
| if command -v zellij &> /dev/null; then | |
| HAS_ZELLIJ=true | |
| echo -e "${GREEN}Found: zellij${NC}" | |
| fi | |
| # Offer appropriate options based on available tools | |
| if [ -n "$ALACRITTY_CMD" ] && [ "$HAS_ZELLIJ" = true ]; then | |
| echo "" | |
| echo -e "${BLUE}Do you want to start a zellij session now?${NC}" | |
| read -p "This will open a new Alacritty terminal (y/N): " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Yy]$ ]]; then | |
| echo -e "${GREEN}Opening new Alacritty terminal with zellij session...${NC}" | |
| "$ALACRITTY_CMD" --working-directory "$WORKTREE_PATH" \ | |
| --command zellij --new-session-with-layout worktree --session "$BRANCH_NAME" & | |
| echo -e "${GREEN}New terminal opened with session '$BRANCH_NAME'${NC}" | |
| else | |
| echo -e "${BLUE}To start a zellij session later:${NC}" | |
| echo -e "${YELLOW} cd $WORKTREE_PATH${NC}" | |
| echo -e "${YELLOW} zellij --new-session-with-layout worktree --session $BRANCH_NAME${NC}" | |
| fi | |
| else | |
| # Missing Alacritty or zellij | |
| if [ -z "$ALACRITTY_CMD" ]; then | |
| echo -e "${YELLOW}Note: Alacritty not found${NC}" | |
| fi | |
| if [ "$HAS_ZELLIJ" = false ]; then | |
| echo -e "${YELLOW}Note: zellij not found${NC}" | |
| fi | |
| echo "" | |
| echo -e "${BLUE}Do you want to cd into the worktree directory?${NC}" | |
| read -p "Press y to print the cd command (y/N): " -n 1 -r | |
| echo "" | |
| if [[ $REPLY =~ ^[Yy]$ ]]; then | |
| echo -e "${YELLOW}Run this command:${NC}" | |
| echo -e " cd $WORKTREE_PATH" | |
| fi | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment