Skip to content

09 — Git Workflow

Savoy Signature Hotels — Branch-per-feature + Worktree development workflow


Every development task — whether a new module, a bug fix, or a refactor — MUST happen on its own isolated git branch inside a dedicated git worktree. Direct commits to main or develop are never allowed for feature work.

main ← stable / production
└── develop ← integration branch (all PRs target this)
└── feat/m14-room-grid ← your feature branch (in its own worktree)

Branch names follow the same prefixes as Conventional Commits:

TypePatternExample
New modulefeat/m{XX}-{kebab-name}feat/m14-room-grid
Featurefeat/{kebab-description}feat/booking-bar-integration
Bug fixfix/{kebab-description}fix/hero-slider-mobile-overflow
Refactorrefactor/{kebab-description}refactor/mapper-shared-types
Documentationdocs/{kebab-description}docs/storybook-guide-update
Chore / infrachore/{kebab-description}chore/upgrade-storybook-10
Style onlystyle/{kebab-description}style/faqs-spacing-fix

Rules:

  • Always lowercase kebab-case after the / — no spaces, no uppercase
  • Module branches always include the number prefix (m{XX})
  • Keep names short and descriptive (3–5 words max after the prefix)

Terminal window
git fetch origin
git branch -r | grep develop || git push origin main:refs/heads/develop

If develop doesn’t exist on the remote, create it from main (run once per project).


Branch off develop, never off main:

Terminal window
git fetch origin
git checkout -b feat/m14-room-grid origin/develop
git push -u origin feat/m14-room-grid

Worktrees let you work on the feature branch without touching the main working directory:

Terminal window
# Go back to main working tree
git checkout main
# Create an isolated worktree for the feature branch
git worktree add ../worktrees/m14-room-grid feat/m14-room-grid
# Move into the worktree
cd ../worktrees/m14-room-grid

Worktree naming: ../worktrees/{branch-short-name} (strip the type prefix, keep the identifier).


All implementation happens inside ../worktrees/{name}/:

  • Write code, SCSS, stories, tests
  • Run pnpm install if needed (pnpm links shared packages)
  • Commit frequently with Conventional Commits:
Terminal window
git add packages/modules/src/m14-room-grid/
git commit -m "feat(m14): add RoomGrid types and mapper"
git commit -m "feat(m14): implement RoomGrid component and SCSS"
git commit -m "test(m14): add RoomGrid mapper and rendering tests"
git commit -m "feat(m14): register RoomGrid in module registry"

Before opening the PR, verify all quality gates pass from inside the worktree:

  • pnpm --filter modules test — all unit tests pass
  • pnpm --filter storybook visual:test — Pixel Perfect visual tests pass
  • pnpm typecheck — no TypeScript errors
  • pnpm lint — no lint errors
  • Max 400 lines changed — split into smaller PRs if larger
  • Visual baselines committed (__figma_baselines__/ + __visual_snapshots__/)

Terminal window
gh pr create \
--base develop \
--title "feat(m14): Room Grid module" \
--body "$(cat <<'EOF'
## Summary
- Implements M14 Room Grid module (Phase A + B)
- Storybook stories with 6 variants
- Mapper + rendering tests
- Pixel Perfect visual tests pass
## Test plan
- [ ] Run `pnpm --filter modules test`
- [ ] Run `pnpm --filter storybook visual:test`
- [ ] Verify all 8 themes render correctly
- [ ] Check responsiveness at 375px, 768px, 1024px, 1440px
🤖 Generated with Claude Code
EOF
)"

Always target develop — never main for feature branches.


Once the PR is merged:

Terminal window
# From repo root (main working tree)
git worktree remove ../worktrees/m14-room-grid
git fetch origin --prune
git branch -d feat/m14-room-grid

BranchWho mergesSource
developVia PR from feature branchesfeat/*, fix/*, refactor/*, etc.
mainVia release PR from developdevelop only

Terminal window
# ── START FEATURE ──────────────────────────────────────
git fetch origin
git checkout -b feat/m{XX}-name origin/develop
git push -u origin feat/m{XX}-name
git checkout main
git worktree add ../worktrees/m{XX}-name feat/m{XX}-name
cd ../worktrees/m{XX}-name
# ── DEVELOP & COMMIT ───────────────────────────────────
git add <files>
git commit -m "feat(m{XX}): ..."
# ── FINISH FEATURE ─────────────────────────────────────
pnpm --filter modules test
pnpm --filter storybook visual:test
gh pr create --base develop --title "feat(m{XX}): ..."
# ── CLEAN UP AFTER MERGE ───────────────────────────────
git worktree remove ../worktrees/m{XX}-name
git branch -d feat/m{XX}-name