Skip to content

Commit 1b47ae8

Browse files
Merge pull request #126 from MobilityData/feat/worktree-scripts
feat: worktree scripts
2 parents d0fcfa9 + 02f2870 commit 1b47ae8

4 files changed

Lines changed: 106 additions & 1 deletion

File tree

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,32 @@ yarn e2e:run
115115
yarn e2e:open
116116
```
117117

118+
## Git Worktrees
119+
120+
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.
121+
122+
### Create a new worktree
123+
124+
```
125+
yarn new-worktree feat/my-feature
126+
```
127+
128+
This will:
129+
1. Create a new branch (`feat/my-feature`) and check it out in a sibling directory named `wt-feat-my-feature`
130+
2. Copy `.vscode` settings and all `.env*` files from the main repo
131+
3. Hard-link `node_modules` from the main repo (fast, minimal extra disk usage) — or run `yarn install` if none exist
132+
4. Open the new worktree in a new VS Code window
133+
134+
> If the new branch changes `package.json` dependencies, run `yarn install` inside the worktree directory to reconcile.
135+
136+
### Remove a worktree
137+
138+
```
139+
yarn remove-worktree feat/my-feature
140+
```
141+
142+
This will remove the worktree directory and delete the local branch. The branch must be fully merged before deletion (uses `git branch -d`).
143+
118144
## API Types Generation
119145

120146
The project includes scripts for generating TypeScript types from OpenAPI specifications:

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@
6969
"generate:api-types:output": "node scripts/generate-api-types.mjs",
7070
"generate:api-types": "node scripts/generate-api-types.mjs src/app/services/feeds/types.ts",
7171
"generate:gbfs-validator-types:output": "npm exec -- openapi-typescript ./external_types/GbfsValidator.yaml -o $npm_config_output_path && eslint $npm_config_output_path --fix",
72-
"generate:gbfs-validator-types": "npm run generate:gbfs-validator-types:output -- --output-file=src/app/services/feeds/gbfs-validator-types.ts"
72+
"generate:gbfs-validator-types": "npm run generate:gbfs-validator-types:output -- --output-file=src/app/services/feeds/gbfs-validator-types.ts",
73+
"new-worktree": "bash scripts/new-worktree.sh",
74+
"remove-worktree": "bash scripts/remove-worktree.sh"
7375
},
7476
"resolutions": {
7577
"tar": "^7.5.7"

scripts/new-worktree.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
3+
# Usage: yarn new-worktree feat/31-my-feature
4+
5+
BRANCH=$1
6+
MAIN_REPO=$(pwd)
7+
WORKTREE_DIR="../wt-$(echo $BRANCH | sed 's/\//-/g')"
8+
9+
if [ -z "$BRANCH" ]; then
10+
echo "❌ Please provide a branch name"
11+
echo "Usage: yarn new-worktree feat/my-feature"
12+
exit 1
13+
fi
14+
15+
# Create the worktree and branch
16+
git worktree add -b $BRANCH $WORKTREE_DIR main
17+
18+
# Copy .vscode if present
19+
if [ -d "$MAIN_REPO/.vscode" ]; then
20+
cp -r "$MAIN_REPO/.vscode" "$WORKTREE_DIR/.vscode"
21+
else
22+
echo "ℹ️ No .vscode directory found in main repo, skipping copy."
23+
fi
24+
25+
# Copy all .env files
26+
for env_file in "$MAIN_REPO"/.env*; do
27+
[ -f "$env_file" ] && cp "$env_file" "$WORKTREE_DIR/$(basename $env_file)"
28+
done
29+
30+
# Copy node_modules via hard links (fast, minimal disk usage)
31+
# Fall back to yarn install if node_modules doesn't exist in main repo
32+
if [ -d "$MAIN_REPO/node_modules" ]; then
33+
echo "📦 Hard-linking node_modules..."
34+
if ! cp -rl "$MAIN_REPO/node_modules" "$WORKTREE_DIR/node_modules"; then
35+
echo "⚠️ Hard-linking node_modules failed, running yarn install..."
36+
(cd "$WORKTREE_DIR" && yarn install)
37+
fi
38+
else
39+
echo "📦 node_modules not found in main repo, running yarn install..."
40+
(cd "$WORKTREE_DIR" && yarn install)
41+
fi
42+
43+
# Open in VSCode
44+
if command -v code &> /dev/null; then
45+
code $WORKTREE_DIR
46+
else
47+
echo "⚠️ VS Code CLI not found. Open the worktree manually: $WORKTREE_DIR"
48+
fi
49+
50+
echo "✅ Worktree ready at $WORKTREE_DIR on branch $BRANCH"
51+

scripts/remove-worktree.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash
2+
3+
# Usage: yarn remove-worktree feat/31-my-feature
4+
5+
BRANCH=$1
6+
WORKTREE_DIR="../wt-$(echo $BRANCH | sed 's/\//-/g')"
7+
8+
if [ -z "$BRANCH" ]; then
9+
echo "❌ Please provide a branch name"
10+
echo "Usage: yarn remove-worktree feat/my-feature"
11+
exit 1
12+
fi
13+
14+
if [ ! -d "$WORKTREE_DIR" ]; then
15+
echo "❌ Worktree directory $WORKTREE_DIR does not exist"
16+
exit 1
17+
fi
18+
19+
# Remove the worktree
20+
git worktree remove "$WORKTREE_DIR"
21+
22+
# Delete the branch
23+
git branch -d $BRANCH
24+
25+
echo "🗑️ Worktree $WORKTREE_DIR removed and branch $BRANCH deleted"
26+

0 commit comments

Comments
 (0)