diff --git a/CLAUDE.md b/CLAUDE.md index fcae41d02..73b2ec4b6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -147,6 +147,29 @@ worktree's source into the worktree's own environment. **Full documentation**: `docs/developer/guides/branching-strategy.md` (Git Worktrees section) +#### Worktree branch policy + +**Worktrees must NEVER be on `development` or `main` directly.** + +In this repo, `main` is the *release* branch (tagged quarterly, essentially +read-only history) and `development` is the integration trunk where active +work converges. The default repository checkout (`~/+Underworld/underworld3-pixi`) +should usually sit on `development` — that's where you read the current +working state and pull updates. All work — even work intended to land +on `development` — happens on a side branch (`feature/...`, `bugfix/...`, +`docs/...`) in a worktree, then merges to `development` via PR. + +`./uw worktree create` enforces this for new worktrees (always on a +side branch, reset to `origin/development`). It's on you not to break +it manually: + +- Never `git checkout development` (or `main`) inside a worktree +- Never `git worktree add ... development` to put a worktree on + `development` directly +- If you find a worktree on `development` (e.g. from older tooling), + branch off immediately (`git switch -c bugfix/whatever`) before + committing + #### Creating and using a worktree ```bash diff --git a/docs/developer/guides/branching-strategy.md b/docs/developer/guides/branching-strategy.md index f4f8f3be0..e538b4bd5 100644 --- a/docs/developer/guides/branching-strategy.md +++ b/docs/developer/guides/branching-strategy.md @@ -155,6 +155,35 @@ one set of dependencies and one (expensive) PETSc compilation. half-finished work. - **Clean PRs**: Each worktree has its own branch, so commits stay focused. +### Branch policy: worktrees are always on a side branch + +**Worktrees must never be on `development` or `main` directly.** + +In this repo, `main` is the *release* branch (tagged quarterly, essentially +read-only history) and `development` is the integration trunk where active +work converges. The default repository checkout +(`~/+Underworld/underworld3-pixi`) should usually sit on `development` — that's +where you read the current working state and pull updates. + +All work — including work intended to land on `development` — happens on a +side branch (`feature/...`, `bugfix/...`, `docs/...`) in a worktree, then +merges to `development` via PR. + +`./uw worktree create` enforces this for new worktrees: it creates the +worktree on `/` and resets to `origin/development`, never +checking out `development` itself in the new worktree. + +**Don't break it manually:** + +- Never `git checkout development` (or `main`) inside a worktree +- Never `git worktree add ... development` to put a worktree directly on + `development` +- If you find a worktree on `development` (e.g. from older tooling), branch + off immediately (`git switch -c bugfix/whatever`) before committing + +The default repo checkout is the *only* place that should be on +`development`. Worktrees are *always* on side branches. + ### Lifecycle ```bash diff --git a/uw b/uw index fcedc68ac..bbba37e14 100755 --- a/uw +++ b/uw @@ -1151,6 +1151,29 @@ worktree_create() { exit 1 fi + # Policy: worktrees must NEVER be on `development` or `main` directly. + # `main` is the release branch (tagged history); `development` is the + # integration trunk and lives in the default repo checkout. All work + # happens on side branches. Refuse misleading prefixes. + if [ "$branch_prefix" = "development" ] || [ "$branch_prefix" = "main" ]; then + local main_repo + main_repo=$(get_main_repo) + echo -e "${YELLOW}Refusing to use '$branch_prefix' as a branch prefix.${NC}" + echo "" + echo "Worktrees in this repo are always on a side branch:" + echo " feature/ bugfix/ docs/ ..." + echo "" + echo "If you wanted a checkout of '$branch_prefix' to read code from," + echo "use the main repo at:" + echo " $main_repo" + echo "" + echo "If you wanted to do work that will merge to development," + echo "use a regular prefix:" + echo " ./uw worktree create $name # → feature/$name" + echo " ./uw worktree create $name bugfix # → bugfix/$name" + exit 1 + fi + local main_repo=$(get_main_repo) local wt_path="$main_repo/.claude/worktrees/$name" local branch_name="${branch_prefix}/${name}" @@ -1324,7 +1347,13 @@ worktree_list() { local dirty="" [ "$status" -gt 0 ] && dirty=" ${YELLOW}($status modified)${NC}" - echo -e " ${GREEN}${wt_name}${NC} [$branch] ($linked)$dirty" + # Policy advisory: worktrees should never be on development or main + local policy="" + if [ "$branch" = "development" ] || [ "$branch" = "main" ]; then + policy=" ${YELLOW}⚠ on '$branch' — branch off to a side branch${NC}" + fi + + echo -e " ${GREEN}${wt_name}${NC} [$branch] ($linked)$dirty$policy" echo " $d" else echo -e " ${YELLOW}${wt_name}${NC} (not a git worktree)"