Git Workflow

Strict worktree-based workflow ensuring main branch integrity and isolated development environments.

Critical Rules

  • NEVER commit to main — protected branch, pre-commit hook enforces
  • NEVER git checkout in main repo — use git worktree for ALL feature work
  • Main repo MUST always stay on main branch

Branch Naming

Format: <prefix>-issue-<number>-<description> or <prefix>-<description>

PrefixPurpose
feat-New features
fix-Bug fixes
chore-Maintenance tasks
hotfix-Urgent production fixes
docs-Documentation
refactor-Code restructuring
test-Test additions

Dashes not slashes — allows using the same name for worktree folder and branch.

Worktree Workflow

# 0. Issue first — no GitHub Issue, no branch
 
# 1. Create worktree
git worktree add ./worktrees/<name> -b <branch>
 
# 2. Sync with main
git fetch origin && git merge origin/main
 
# 3. Setup and start
cd renewa-one && make dev-init    # See [[Makefile Commands]]
 
# 4. Implement + quality checks
make typecheck && make lint && make test
 
# 5. Push + create PR
git push origin <branch> && gh pr create --draft

Quick start: renewa-one/scripts/issue-to-worktree.sh <issue-number> "<description>" (see Scripts)

Pre-Push Conflict Check

MANDATORY before every git push:

git fetch origin main && git merge origin/main

Never push a branch that would show merge conflicts on GitHub.

Git Hooks (Local Safety Net — CI Is The Gate)

HookSpeedChecks
Pre-commit~5sFormat + lint staged files, block main, no binaries in docs/, migration consistency, English-only identifiers, LocalizedText validation, i18n parity
Pre-push<30sConflict check vs origin/main, changelog fragment, atlas.sum integrity (only when migrations touched)

Pre-push deliberately does NOT run typecheck or tests anymore (PR#1624) — CI runs them in parallel sharded jobs faster than serial Docker on dev hardware. The IDE LSP gives continuous typecheck; run make typecheck / make test manually if wanted.

Hooks installed via scripts/setup-git-hooks.sh. See Scripts for details.

Claude Code PostToolUse Hook

Every Edit/Write on .ts/.tsx/.js/.jsx under renewa-one/{backend,frontend,shared}/src/ runs scripts/quick-lint.sh (<100ms) via .claude/settings.json. It catches 11 codified anti-patterns (deprecated verify*Ownership guards, mock.module('@/db'), sql.raw, module-scope setInterval, buffer storage helpers, as Email, Number() on money columns, inline useQuery/useMutation + raw useSearchParams, HubSpot owner isolation, recordOwnerContactId writes, persistence topology I#2013). Zero-false-positive policy: fuzzier checks belong in ESLint.

Branch Protection (GitHub Ruleset)

RulePurpose
required_status_checks (ci-gate)CI must pass
pull_requestPRs required, stale reviews dismissed, 0 approvals (author = reviewer)
required_linear_historySquash merges only
non_fast_forwardNo force pushes to main
deletionCannot delete main

PR Rules

  • Title format: Add payment integration (#123) (with issue) or Add user authentication system (without)
  • Corrections: Never create new branches — reuse existing branch/worktree
  • Squash merges only
  • Handoff protocol: Draft PR = author actively working; Ready for Review = reviewers take ownership. Stacked PRs branch from the feature branch with --base.

Changelog Fragments

Required for PRs changing frontend/src/, backend/, or shared/:

  • Location: renewa-one/frontend/changelog/{de,en}/<branch-name>.md
  • Exempt prefixes: chore-, docs-, test-, refactor-
  • Enforced by pre-push hook + [[CI-CD Workflows|CI changelog-check job]]
  • Audience is operators and end users (Teams “Updates” digest): user-visible behaviour only, ≤200 chars/bullet, ≤8 bullets per locale

Cleanup

After PR merge: ./scripts/cleanup-merged-worktrees.sh (--dry-run to preview, --auto for no-prompt)

See Also