OneApp Docs
Guides

Git Workflow

Master the git workflow used across the OneApp monorepo — from branch naming and conventional commits to PR reviews and the Mergify merge queue.

Already know git basics?

Why git workflow matters

Working without a clear git workflow creates serious problems:

  • Messy commit history — No standard format, can't tell what changed or why
  • Merge conflicts — Teams step on each other's toes, waste hours resolving conflicts
  • Failed deployments — Commit trailers like Co-Authored-By: break Vercel deploys
  • No release tracking — Can't identify which commits should trigger releases
  • Review chaos — PRs lack context, reviewers don't know what to focus on
  • Branch confusion — Can't tell if auth-fix is a feature, bug fix, or refactor

OneApp's git workflow uses conventional commits (semantic versioning automation), branch prefixes (feature/, fix/, docs/), PR templates (consistent context), Mergify merge queue (intelligent batching), Changesets (version management), and branch protection (enforce quality checks) — ensuring clean history and reliable releases.

Production-ready with Husky 9 git hooks (validate commits), automated commit message validation, squash merges only (clean history), 1+ required reviewers, all CI checks must pass, and Renovate auto-merge for dependencies.

Use cases

Master this workflow to:

  • Ship features confidently — Clear PR process with automated checks
  • Collaborate effectively — Standard branch naming, no stepping on toes
  • Release reliably — Changesets track what should be released
  • Review efficiently — PR templates provide consistent context
  • Resolve conflicts quickly — Rebase strategy keeps history clean
  • Automate releases — Conventional commits drive semantic versioning

Quick Start

Essential workflow

1. Create a feature branch:

# Start from latest main
git checkout main
git pull origin main
git checkout -b feature/my-feature

2. Make changes and commit:

# Stage changes
git add .

# Commit with conventional format
git commit -m "feat: add user authentication"

3. Push and create PR:

# Push to remote
git push -u origin feature/my-feature

# Create PR via GitHub CLI
gh pr create --title "feat: add user authentication"

4. After approval:

# Add ready-to-merge label (triggers Mergify)
gh pr edit --add-label ready-to-merge

That's it! Mergify handles batching and merging automatically.

Branch strategy

Branch naming conventions

Use descriptive prefixes to indicate branch purpose:

PrefixPurposeExampleWhen to Use
feature/New featuresfeature/user-authenticationAdding new functionality
fix/Bug fixesfix/login-redirectFixing broken behavior
refactor/Code refactoringrefactor/api-clientImproving code without changing behavior
docs/Documentationdocs/api-referenceDocumentation-only changes
chore/Maintenancechore/update-dependenciesDependencies, tooling, cleanup
test/Testingtest/add-unit-testsAdding or updating tests
perf/Performanceperf/optimize-queriesPerformance improvements

Examples:

# Good branch names
git checkout -b feature/dark-mode
git checkout -b fix/memory-leak
git checkout -b docs/getting-started
git checkout -b refactor/error-handling

# Bad branch names
git checkout -b my-branch           # No context
git checkout -b john-work           # Not descriptive
git checkout -b fix                 # Too generic

Creating branches

From main
# Always start from latest main
git checkout main
git pull origin main
git checkout -b feature/my-feature
From another branch
# Create branch from specific point
git checkout -b feature/my-feature origin/main
From a commit
# Create branch from specific commit
git checkout -b fix/rollback abc123

Commit conventions

We use Conventional Commits for semantic versioning and changelog generation.

Commit message format

<type>(<scope>): <description>

[optional body]

[optional footer]

Components:

  • type: Category of change (feat, fix, docs, etc.)
  • scope: Optional package/area affected (@repo/ui, auth, etc.)
  • description: Brief summary (lowercase, no period)
  • body: Detailed explanation (optional)
  • footer: Breaking changes, issue refs (optional)

Commit types

TypeDescriptionExampleTriggers Release?
featNew featurefeat: add dark mode✅ Minor
fixBug fixfix: resolve login issue✅ Patch
docsDocumentationdocs: update README❌ No
styleFormattingstyle: fix indentation❌ No
refactorCode changerefactor: simplify logic❌ No
perfPerformanceperf: optimize queries✅ Patch
testTeststest: add unit tests❌ No
choreMaintenancechore: update deps❌ No
ciCI/CDci: add build cache❌ No
buildBuild systembuild: update webpack❌ No
revertRevert commitrevert: feat: add feature✅ Patch

Commit examples

Simple commits
# Feature
git commit -m "feat: add user authentication"

# Bug fix
git commit -m "fix: resolve login redirect issue"

# Documentation
git commit -m "docs: update API reference"

# Refactoring
git commit -m "refactor: simplify error handling logic"

# Performance
git commit -m "perf: cache database queries"
With scope
# Scope indicates affected package
git commit -m "feat(@repo/ui): add Button component"
git commit -m "fix(@repo/auth): handle expired tokens"
git commit -m "docs(api): add endpoint documentation"
With body
# Complex changes need explanation
git commit -m "feat: implement caching layer

- Add Redis client configuration
- Implement cache invalidation strategy
- Add cache hit/miss metrics
- Update documentation"
Breaking changes
# Use BREAKING CHANGE in footer
git commit -m "feat: redesign authentication API

BREAKING CHANGE: Auth endpoints now require Bearer token instead of API key.
Migration guide available at /docs/migration/auth-v2"

Never add commit trailers

Critical: Do NOT add Co-Authored-By:, Signed-off-by:, or other trailers — they break Vercel deployments.

# ❌ Bad - breaks deployment
git commit -m "feat: add feature

Co-Authored-By: John <john@example.com>"

# ✅ Good - clean commit
git commit -m "feat: add feature"

Use GitHub's PR co-author attribution instead.

Pull Request workflow

Before creating a PR

1. Update your branch:

# Rebase on latest main
git fetch origin main
git rebase origin/main

# Resolve conflicts if needed
git add <resolved-files>
git rebase --continue

2. Run quality checks:

# Full quality check (required)
pnpm build && pnpm lint && pnpm typecheck

# Or run individually
pnpm build      # Ensure code compiles
pnpm lint       # Check code quality
pnpm typecheck  # Verify TypeScript types

3. Push your branch:

# First push
git push -u origin feature/my-feature

# Subsequent pushes
git push

Creating the PR

Using GitHub CLI (recommended)
# Create PR interactively
gh pr create

# Or with all details
gh pr create \
  --title "feat: add user authentication" \
  --body "Implements user authentication with Better Auth"
Using web interface
# Push and visit:
# https://github.com/OneDigital-Product/monorepo/pull/new/feature/my-feature

PR requirements

Title:

  • Use conventional commit format
  • Examples: feat: add dark mode, fix: resolve memory leak

Description:

  • Explain what changed
  • Explain why it changed
  • Include testing steps
  • Add screenshots for UI changes

Checklist:

  • All CI checks pass
  • Code reviewed by 1+ reviewer
  • Tests added/updated
  • Documentation updated (if needed)
  • Changeset created (if needed)

PR template

Our automated PR template includes:

## Summary

Brief description of what this PR does.

## Changes

- Added X
- Updated Y
- Fixed Z

## Testing

How to test these changes:

1. Step 1
2. Step 2
3. Expected result

## Changeset

- [ ] Changeset created (if applicable)
- [ ] Breaking changes documented

## Screenshots

Include before/after for UI changes.

Code review process

For reviewers

Focus on:

  • ✅ Logic correctness and edge cases
  • ✅ Type safety and null handling
  • ✅ Error handling and validation
  • ✅ Performance implications
  • ✅ Security considerations
  • ✅ Test coverage

Be constructive:

  • Suggest improvements, don't just criticize
  • Explain the "why" behind suggestions
  • Acknowledge good code
  • Use GitHub suggestions for code changes

Review checklist:

  • Code logic is correct
  • No any types used
  • Error handling is comprehensive
  • Tests cover new functionality
  • Documentation is updated
  • No security vulnerabilities

For authors

Responding to feedback:

  • Address all comments
  • Explain decisions if you disagree
  • Update code based on suggestions
  • Mark conversations as resolved
  • Request re-review when ready

Common review comments:

  • "Add error handling" — Handle edge cases
  • "Extract to utility" — Reduce duplication
  • "Add tests" — Cover new functionality
  • "Type this properly" — Avoid any types

Mergify merge queue

The repo uses Mergify for intelligent merge queue management.

How it works

1. Approval and ready:

# After PR is approved, add label
gh pr edit --add-label ready-to-merge

2. Mergify batching:

  • Groups compatible PRs together
  • Runs CI on batched changes
  • Reduces redundant CI runs

3. Automatic merge:

  • Merges if all checks pass
  • Deletes branch automatically
  • Updates related issues

Batch strategy

PRs are batched based on:

  • Affected packages — UI changes batched separately from API changes
  • Priority labelspriority: high merges first
  • Dependencies — Dependent PRs merge in order

Priority labels:

  • priority: high — Security fixes, critical bugs
  • priority: normal — Features, regular fixes (default)
  • priority: low — Refactoring, documentation

Changesets

For changes that should trigger releases, create a changeset.

When to create changesets

Change TypeChangeset?Version Bump
New features✅ YesMinor (0.X.0)
Bug fixes✅ YesPatch (0.0.X)
Breaking changes✅ YesMajor (X.0.0)
Documentation❌ No-
Internal refactoring❌ No-
CI/CD changes❌ No-
Dependencies (non-breaking)❌ No-

Creating a changeset

# Interactive changeset creation
pnpm changeset

# Follow prompts:
# 1. Select affected packages (space to select, enter to confirm)
# 2. Select version bump type (major, minor, patch)
# 3. Write summary (markdown supported)

Changeset examples

.changeset/happy-dogs-dance.md
---
"@repo/ui": minor
---

Add dark mode support to Button component

- New `variant="dark"` prop
- Automatic theme detection with `useTheme()` hook
- Updated documentation with dark mode examples
.changeset/sad-cats-cry.md
---
"@repo/auth": major
---

BREAKING: Redesign authentication API

- Changed auth endpoints to require Bearer tokens
- Removed deprecated `apiKey` parameter
- See migration guide: /docs/migration/auth-v2

Next steps

For Developers: Advanced git operations and troubleshooting

Advanced git operations

Resolving merge conflicts

# Update your branch
git fetch origin main
git rebase origin/main

# Conflicts will be marked in files:
# <<<<<<< HEAD
# Your changes
# =======
# Their changes
# >>>>>>> origin/main

# Resolve conflicts in files, then:
git add <resolved-files>
git rebase --continue

# Force push (safe on feature branches)
git push --force-with-lease

Interactive rebase

# Rebase last 3 commits
git rebase -i HEAD~3

# Options:
# pick   - keep commit as-is
# reword - change commit message
# edit   - amend commit
# squash - combine with previous
# drop   - remove commit

# Example: squash commits
# pick abc123 feat: add feature
# squash def456 fix: typo
# squash ghi789 fix: another typo

Cherry-picking commits

# Apply specific commit to current branch
git cherry-pick abc123

# Cherry-pick multiple commits
git cherry-pick abc123 def456

# Cherry-pick without committing
git cherry-pick --no-commit abc123

Stashing changes

# Save current changes
git stash save "work in progress"

# List stashes
git stash list

# Apply latest stash
git stash pop

# Apply specific stash
git stash apply stash@{1}

# Drop stash
git stash drop stash@{0}

Undoing changes

# Undo last commit (keep changes)
git reset --soft HEAD~1

# Undo last commit (discard changes)
git reset --hard HEAD~1

# Undo specific file
git checkout HEAD -- <file>

# Revert commit (creates new commit)
git revert abc123

Amending commits

# Amend last commit message
git commit --amend -m "new message"

# Amend last commit (add files)
git add <forgotten-file>
git commit --amend --no-edit

# Force push (only on unpushed commits!)
git push --force-with-lease

Amend with caution

Only amend commits that haven't been pushed. Amending pushed commits rewrites history and can cause problems for collaborators.

Check authorship before amending:

git log -1 --format='%an %ae'

If it's not your commit, create a new commit instead.

Git best practices

Commit frequency

# ✅ Good - atomic commits
git commit -m "feat: add user model"
git commit -m "feat: add user service"
git commit -m "feat: add user routes"

# ❌ Bad - giant commit
git commit -m "feat: add entire user system"

Branch hygiene

# Delete merged branches
git branch --merged | grep -v "main" | xargs git branch -d

# Delete remote branches
git fetch --prune

# Update local branches
git fetch --all

Commit message quality

# ✅ Good - clear and specific
git commit -m "fix: prevent null pointer in user lookup"

# ❌ Bad - vague
git commit -m "fix bug"
git commit -m "update code"
git commit -m "changes"

Troubleshooting

Accidentally committed to main

# Undo commit (keep changes)
git reset --soft HEAD~1

# Create feature branch
git checkout -b feature/my-feature

# Push to feature branch
git push -u origin feature/my-feature

Wrong commit message

# If not pushed yet
git commit --amend -m "correct message"

# If already pushed
git revert abc123  # Better to create new commit

Lost commits

# Find lost commits
git reflog

# Restore lost commit
git checkout <commit-hash>
git checkout -b recovered-work

Large file accidentally committed

# Remove from last commit
git rm --cached <large-file>
git commit --amend --no-edit

# Remove from history (use with caution)
git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch <large-file>" \
  --prune-empty --tag-name-filter cat -- --all

Merge vs Rebase

Use rebase:

  • ✅ Feature branches (keeps history clean)
  • ✅ Before creating PR (update with latest main)
  • ✅ Personal branches (no collaborators)

Use merge:

  • ✅ Merging PRs (squash merge)
  • ✅ Shared branches (multiple collaborators)
  • ✅ Release branches (preserve history)
# Rebase workflow (clean history)
git fetch origin main
git rebase origin/main
git push --force-with-lease

# Merge workflow (preserve history)
git fetch origin main
git merge origin/main
git push

GitHub CLI shortcuts

# Create PR
gh pr create --fill

# View PR status
gh pr status

# Checkout PR locally
gh pr checkout 123

# Merge PR
gh pr merge 123 --squash --delete-branch

# View PR checks
gh pr checks

# Review PR
gh pr review 123 --approve
gh pr review 123 --request-changes -b "Please add tests"

# Add reviewers
gh pr edit 123 --add-reviewer @username

# Add labels
gh pr edit 123 --add-label ready-to-merge

On this page