From 3d4afd557b3034d19cbf1ab956d5cf5e5af226b3 Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Tue, 21 Apr 2026 14:01:02 -0400 Subject: [PATCH 1/4] worktree scripts --- README.md | 26 +++++++++++++++++++++++++ package.json | 4 +++- scripts/new-worktree.sh | 40 ++++++++++++++++++++++++++++++++++++++ scripts/remove-worktree.sh | 26 +++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100755 scripts/new-worktree.sh create mode 100755 scripts/remove-worktree.sh diff --git a/README.md b/README.md index 2ab4092..ea0265f 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,32 @@ yarn e2e:run yarn e2e:open ``` +## Git Worktrees + +The project includes scripts to manage [Git worktrees](https://git-scm.com/docs/git-worktree), allowing you to work on multiple branches simultaneously in separate directories without stashing or switching branches. + +### Create a new worktree + +``` +yarn new-worktree feat/my-feature +``` + +This will: +1. Create a new branch (`feat/my-feature`) and check it out in a sibling directory named `wt-feat-my-feature` +2. Copy `.vscode` settings and all `.env*` files from the main repo +3. Hard-link `node_modules` from the main repo (fast, minimal extra disk usage) — or run `yarn install` if none exist +4. Open the new worktree in a new VS Code window + +> If the new branch changes `package.json` dependencies, run `yarn install` inside the worktree directory to reconcile. + +### Remove a worktree + +``` +yarn remove-worktree feat/my-feature +``` + +This will remove the worktree directory and delete the local branch. The branch must be fully merged before deletion (uses `git branch -d`). + ## API Types Generation The project includes scripts for generating TypeScript types from OpenAPI specifications: diff --git a/package.json b/package.json index 63d219c..e42b156 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,9 @@ "generate:api-types:output": "node scripts/generate-api-types.mjs", "generate:api-types": "node scripts/generate-api-types.mjs src/app/services/feeds/types.ts", "generate:gbfs-validator-types:output": "npm exec -- openapi-typescript ./external_types/GbfsValidator.yaml -o $npm_config_output_path && eslint $npm_config_output_path --fix", - "generate:gbfs-validator-types": "npm run generate:gbfs-validator-types:output -- --output-file=src/app/services/feeds/gbfs-validator-types.ts" + "generate:gbfs-validator-types": "npm run generate:gbfs-validator-types:output -- --output-file=src/app/services/feeds/gbfs-validator-types.ts", + "new-worktree": "bash scripts/new-worktree.sh", + "remove-worktree": "bash scripts/remove-worktree.sh" }, "resolutions": { "tar": "^7.5.7" diff --git a/scripts/new-worktree.sh b/scripts/new-worktree.sh new file mode 100755 index 0000000..546daba --- /dev/null +++ b/scripts/new-worktree.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# Usage: yarn new-worktree feat/31-my-feature + +BRANCH=$1 +MAIN_REPO=$(pwd) +WORKTREE_DIR="../wt-$(echo $BRANCH | sed 's/\//-/g')" + +if [ -z "$BRANCH" ]; then + echo "❌ Please provide a branch name" + echo "Usage: yarn new-worktree feat/my-feature" + exit 1 +fi + +# Create the worktree and branch +git worktree add -b $BRANCH $WORKTREE_DIR main + +# Copy .vscode +cp -r "$MAIN_REPO/.vscode" "$WORKTREE_DIR/.vscode" + +# Copy all .env files +for env_file in "$MAIN_REPO"/.env*; do + [ -f "$env_file" ] && cp "$env_file" "$WORKTREE_DIR/$(basename $env_file)" +done + +# Copy node_modules via hard links (fast, minimal disk usage) +# Fall back to yarn install if node_modules doesn't exist in main repo +if [ -d "$MAIN_REPO/node_modules" ]; then + echo "đŸ“Ļ Hard-linking node_modules..." + cp -rl "$MAIN_REPO/node_modules" "$WORKTREE_DIR/node_modules" +else + echo "đŸ“Ļ node_modules not found in main repo, running yarn install..." + cd $WORKTREE_DIR && yarn install +fi + +# Open in VSCode +code $WORKTREE_DIR + +echo "✅ Worktree ready at $WORKTREE_DIR on branch $BRANCH" + \ No newline at end of file diff --git a/scripts/remove-worktree.sh b/scripts/remove-worktree.sh new file mode 100755 index 0000000..4ecad8a --- /dev/null +++ b/scripts/remove-worktree.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# Usage: yarn remove-worktree feat/31-my-feature + +BRANCH=$1 +WORKTREE_DIR="../wt-$(echo $BRANCH | sed 's/\//-/g')" + +if [ -z "$BRANCH" ]; then + echo "❌ Please provide a branch name" + echo "Usage: yarn remove-worktree feat/my-feature" + exit 1 +fi + +if [ ! -d "$WORKTREE_DIR" ]; then + echo "❌ Worktree directory $WORKTREE_DIR does not exist" + exit 1 +fi + +# Remove the worktree +git worktree remove "$WORKTREE_DIR" + +# Delete the branch +git branch -d $BRANCH + +echo "đŸ—‘ī¸ Worktree $WORKTREE_DIR removed and branch $BRANCH deleted" + \ No newline at end of file From f0f6440fe56f71e638f5662cddb7f99fa6a3652a Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Tue, 21 Apr 2026 14:07:28 -0400 Subject: [PATCH 2/4] make opening vscode optional --- scripts/new-worktree.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/new-worktree.sh b/scripts/new-worktree.sh index 546daba..baea4ba 100755 --- a/scripts/new-worktree.sh +++ b/scripts/new-worktree.sh @@ -34,7 +34,11 @@ else fi # Open in VSCode -code $WORKTREE_DIR +if command -v code &> /dev/null; then + code $WORKTREE_DIR +else + echo "âš ī¸ VS Code CLI not found. Open the worktree manually: $WORKTREE_DIR" +fi echo "✅ Worktree ready at $WORKTREE_DIR on branch $BRANCH" \ No newline at end of file From d4a1fba6bd630db93765e2340cc839baafff3171 Mon Sep 17 00:00:00 2001 From: Alessandro Kreslin Date: Tue, 21 Apr 2026 14:41:45 -0400 Subject: [PATCH 3/4] Update scripts/new-worktree.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- scripts/new-worktree.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/new-worktree.sh b/scripts/new-worktree.sh index baea4ba..69369e9 100755 --- a/scripts/new-worktree.sh +++ b/scripts/new-worktree.sh @@ -15,8 +15,12 @@ fi # Create the worktree and branch git worktree add -b $BRANCH $WORKTREE_DIR main -# Copy .vscode -cp -r "$MAIN_REPO/.vscode" "$WORKTREE_DIR/.vscode" +# Copy .vscode if present +if [ -d "$MAIN_REPO/.vscode" ]; then + cp -r "$MAIN_REPO/.vscode" "$WORKTREE_DIR/.vscode" +else + echo "â„šī¸ No .vscode directory found in main repo, skipping copy." +fi # Copy all .env files for env_file in "$MAIN_REPO"/.env*; do From 02f2870dd147ed314206acfb4ace4c394f657777 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:44:43 +0000 Subject: [PATCH 4/4] fix: fallback to yarn install when node_modules hard-linking fails Agent-Logs-Url: https://github.com/MobilityData/mobilitydatabase-web/sessions/b94c36ed-c130-4c94-b685-7e7ba5ecd4c9 Co-authored-by: Alessandro100 <18631060+Alessandro100@users.noreply.github.com> --- scripts/new-worktree.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/new-worktree.sh b/scripts/new-worktree.sh index 69369e9..0d7d45a 100755 --- a/scripts/new-worktree.sh +++ b/scripts/new-worktree.sh @@ -31,10 +31,13 @@ done # Fall back to yarn install if node_modules doesn't exist in main repo if [ -d "$MAIN_REPO/node_modules" ]; then echo "đŸ“Ļ Hard-linking node_modules..." - cp -rl "$MAIN_REPO/node_modules" "$WORKTREE_DIR/node_modules" + if ! cp -rl "$MAIN_REPO/node_modules" "$WORKTREE_DIR/node_modules"; then + echo "âš ī¸ Hard-linking node_modules failed, running yarn install..." + (cd "$WORKTREE_DIR" && yarn install) + fi else echo "đŸ“Ļ node_modules not found in main repo, running yarn install..." - cd $WORKTREE_DIR && yarn install + (cd "$WORKTREE_DIR" && yarn install) fi # Open in VSCode @@ -45,4 +48,4 @@ else fi echo "✅ Worktree ready at $WORKTREE_DIR on branch $BRANCH" - \ No newline at end of file +