Files
rdbms-playground/scripts/wt-new.sh
T
claude@clouddev1 b5c848efcb
ci / gate (push) Successful in 2m5s
ci / manifests (push) Successful in 4s
ci / gate (pull_request) Successful in 2m5s
ci / manifests (pull_request) Successful in 4s
chore(workflow): branch-and-PR working method + ADR-number reservation (ADR-0059)
Adopt a trackable working method now the repo is public:
- PRs onto a protected main; --no-ff merge commits; one worktree per branch.
- Reserve-first ADR numbering: scripts/adr-reserve.sh claims the next number
  atomically against main (push = compare-and-swap; ledger
  docs/adr/RESERVATIONS.log), so a number is stable from creation.
- Worktree helpers scripts/wt-new.sh + wt-clean.sh.
- Local-origin test harnesses (reserve 10/10, worktrees 7/7, shellcheck clean).

Record the decision in ADR-0059, supersede ADR-0000's placeholder-until-merge
numbering default, and add the lean CONTRIBUTING.md sections + CLAUDE.md
operational rules.
2026-06-23 20:41:42 +00:00

55 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# wt-new.sh — start a branch in its own git worktree.
#
# WHY: every branch is developed in an isolated worktree, never by switching
# the primary checkout (two shells in one checkout is how you clobber work).
# This creates the branch off an up-to-date `main` and a sibling worktree
# named to match the repo's existing convention:
#
# <parent>/<repo>-worktree-<last-segment-of-branch>
# e.g. feat/clause-concept-hints -> ../rdbms-playground-worktree-clause-concept-hints
#
# USAGE
# scripts/wt-new.sh <branch>
# scripts/wt-new.sh feat/clause-concept-hints
#
# Prints the new worktree path; cd there to start working.
set -euo pipefail
log() { printf ' wt-new: %s\n' "$*" >&2; }
die() { printf 'wt-new: ERROR: %s\n' "$*" >&2; exit 1; }
[ $# -eq 1 ] || die "usage: wt-new.sh <branch> (e.g. feat/my-thing)"
branch="$1"
# Conventional prefixes keep branch names aligned with commit types.
case "$branch" in
feat/*|fix/*|docs/*|chore/*|refactor/*|test/*|ci/*) : ;;
*) die "branch should start with feat/ fix/ docs/ chore/ refactor/ test/ ci/ (got: $branch)" ;;
esac
git rev-parse --git-dir >/dev/null 2>&1 || die "not inside a git repo"
# Sibling-of-the-primary-checkout location, matching existing worktrees.
main_wt="$(git worktree list --porcelain | awk '/^worktree /{print $2; exit}')"
parent="$(dirname "$main_wt")"
repo="$(basename "$main_wt")"
seg="${branch##*/}"
target="$parent/${repo}-worktree-${seg}"
[ -e "$target" ] && die "worktree path already exists: $target"
git show-ref --verify --quiet "refs/heads/$branch" \
&& die "branch already exists: $branch (use 'git worktree add' to attach a worktree to it)"
log "fetching origin/main"
git fetch --quiet origin main || die "git fetch origin main failed"
log "creating branch '$branch' + worktree at $target"
git worktree add --quiet -b "$branch" "$target" origin/main \
|| die "git worktree add failed"
log "ready — cd into it:"
echo "$target"