Created
September 18, 2025 00:36
-
-
Save drnic/8c18d4edc3829512f52f89afefc793d3 to your computer and use it in GitHub Desktop.
bin/worktree to create/list/destroy worktrees where 1) bin/setup expects to setup databases; 2) some .gitignored files copied over; etc
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
#!/usr/bin/env bash | |
set -euo pipefail | |
# Usage/help | |
usage() { | |
echo "Usage: bin/worktree <branch-name>" | |
echo " bin/worktree --destroy <branch-name>" | |
echo " bin/worktree -d <branch-name>" | |
echo "" | |
echo "Creates or destroys a git worktree and sets up Rails environment with unique database names." | |
exit 1 | |
} | |
LIST_MODE=false | |
DESTROY_MODE=false | |
if [ $# -eq 0 ]; then | |
usage | |
fi | |
if [ $# -gt 0 ] && { [ "$1" = "--list" ] || [ "$1" = "-l" ]; }; then | |
LIST_MODE=true | |
shift | |
fi | |
if [ $# -gt 0 ] && { [ "$1" = "--destroy" ] || [ "$1" = "-d" ]; }; then | |
DESTROY_MODE=true | |
shift | |
fi | |
ROOT_FOLDER=$(basename "$(pwd)") | |
WORKTREES_PARENT="../${ROOT_FOLDER}-worktrees" | |
CURRENT_DIR=$(pwd) | |
if [ "$LIST_MODE" = true ]; then | |
echo "π Listing git worktrees:" | |
git worktree list | |
exit 0 | |
fi | |
if [ $# -eq 0 ]; then | |
usage | |
fi | |
BRANCH_NAME="$1" | |
FLATTENED_BRANCH_NAME="${BRANCH_NAME//\//_}" | |
WORKTREE_DIR="$WORKTREES_PARENT/$FLATTENED_BRANCH_NAME" | |
# Clean branch name for database naming (replace special chars) | |
DB_SUFFIX=$(echo "$FLATTENED_BRANCH_NAME" | sed 's/[^a-zA-Z0-9]/_/g' | tr '[:upper:]' '[:lower:]') | |
if [ "$DESTROY_MODE" = true ]; then | |
echo "β οΈ Destroying worktree for branch: $BRANCH_NAME" | |
if [ ! -d "$WORKTREE_DIR" ]; then | |
echo "β Worktree directory does not exist: $WORKTREE_DIR" | |
exit 1 | |
fi | |
cd "$WORKTREE_DIR" | |
echo "ποΈ Dropping Rails databases for branch..." | |
# Drop development DB | |
if bin/rails db:drop; then | |
echo "β Dropped development database" | |
else | |
echo "β οΈ Could not drop development database (may not exist)" | |
fi | |
# Drop test DB | |
if bin/rails db:drop RAILS_ENV=test; then | |
echo "β Dropped test database" | |
else | |
echo "β οΈ Could not drop test database (may not exist)" | |
fi | |
cd "$CURRENT_DIR" | |
echo "ποΈ Removing worktree directory..." | |
if git worktree remove "$WORKTREE_DIR" --force; then | |
echo "β Removed git worktree" | |
else | |
echo "β οΈ Failed to remove git worktree (may not be registered)" | |
fi | |
if rm -rf "$WORKTREE_DIR"; then | |
echo "β Deleted worktree directory" | |
else | |
echo "β οΈ Failed to delete worktree directory" | |
fi | |
echo "πΏ Deleting branch..." | |
if git branch -D "$BRANCH_NAME" 2>/dev/null; then | |
echo "β Deleted branch: $BRANCH_NAME" | |
else | |
echo "β οΈ Failed to delete branch (may not exist locally or may be current branch)" | |
fi | |
echo "π Worktree destruction complete!" | |
exit 0 | |
fi | |
echo "Creating git worktree for branch: $BRANCH_NAME" | |
# Create worktrees directory if it doesn't exist | |
mkdir -p "../${ROOT_FOLDER}-worktrees" | |
# Create the git worktree | |
# Determine if branch exists locally or remotely | |
if git rev-parse --verify "$BRANCH_NAME" >/dev/null 2>&1; then | |
# Branch exists, add worktree normally | |
if git worktree add "$WORKTREE_DIR" "$BRANCH_NAME"; then | |
echo "β Git worktree created at: $WORKTREE_DIR" | |
else | |
echo "β Failed to create git worktree" | |
exit 1 | |
fi | |
else | |
# Branch does not exist, create it with -b flag | |
if git worktree add "$WORKTREE_DIR" -b "$BRANCH_NAME"; then | |
echo "β Git worktree created (new branch) at: $WORKTREE_DIR" | |
else | |
echo "β Failed to create git worktree (new branch)" | |
exit 1 | |
fi | |
fi | |
echo "π Copying important Rails configuration files..." | |
# Copy other important gitignored files that might exist | |
for file in .env CLAUDE.md .claude .cursorrules .cursor .developer.rb LogConfig.yml .mcp.json .vscode ; do | |
if [ -e "$file" ]; then | |
cp -r "$file" "$WORKTREE_DIR/" | |
echo "β Copied $file" | |
fi | |
done | |
# Copy Rails credentials | |
if [ -d "config/credentials" ]; then | |
cp -r "config/credentials" "$WORKTREE_DIR/config/" | |
echo "β Copied Rails credentials" | |
fi | |
echo "ποΈ Setting up unique database configuration..." | |
# Append database environment variables to .env | |
cat >> "$WORKTREE_DIR/.env" << EOF | |
# Worktree-specific database configuration | |
BRANCH_DATABASE=true | |
PGDATABASE=$(echo "sc_coregem_dev_${DB_SUFFIX}" | cut -c1-63) | |
TEST_ENV_NUMBER=_${DB_SUFFIX} | |
EOF | |
echo "β Added unique database configuration to .env" | |
# Change to the worktree directory and run setup | |
cd "$WORKTREE_DIR" | |
echo "π§ Running bin/setup in worktree with mise exec..." | |
if command -v mise >/dev/null 2>&1; then | |
if mise exec -- bin/setup; then | |
echo "β Setup completed successfully" | |
else | |
echo "β οΈ Setup encountered issues - you may need to run it manually" | |
fi | |
else | |
if ./bin/setup; then | |
echo "β Setup completed successfully" | |
else | |
echo "β οΈ Setup encountered issues - you may need to run it manually" | |
fi | |
fi | |
# Return to original directory | |
cd "$CURRENT_DIR" | |
echo "" | |
echo "π Worktree setup complete!" | |
echo "" | |
echo "To change into the new worktree directory, run:" | |
if command -v direnv >/dev/null 2>&1; then | |
echo "cd $WORKTREE_DIR; direnv allow" | |
else | |
echo "cd $WORKTREE_DIR" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment