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-fixis 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-feature2. 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-mergeThat's it! Mergify handles batching and merging automatically.
Branch strategy
Branch naming conventions
Use descriptive prefixes to indicate branch purpose:
| Prefix | Purpose | Example | When to Use |
|---|---|---|---|
feature/ | New features | feature/user-authentication | Adding new functionality |
fix/ | Bug fixes | fix/login-redirect | Fixing broken behavior |
refactor/ | Code refactoring | refactor/api-client | Improving code without changing behavior |
docs/ | Documentation | docs/api-reference | Documentation-only changes |
chore/ | Maintenance | chore/update-dependencies | Dependencies, tooling, cleanup |
test/ | Testing | test/add-unit-tests | Adding or updating tests |
perf/ | Performance | perf/optimize-queries | Performance 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 genericCreating branches
# Always start from latest main
git checkout main
git pull origin main
git checkout -b feature/my-feature# Create branch from specific point
git checkout -b feature/my-feature origin/main# Create branch from specific commit
git checkout -b fix/rollback abc123Commit 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
| Type | Description | Example | Triggers Release? |
|---|---|---|---|
feat | New feature | feat: add dark mode | ✅ Minor |
fix | Bug fix | fix: resolve login issue | ✅ Patch |
docs | Documentation | docs: update README | ❌ No |
style | Formatting | style: fix indentation | ❌ No |
refactor | Code change | refactor: simplify logic | ❌ No |
perf | Performance | perf: optimize queries | ✅ Patch |
test | Tests | test: add unit tests | ❌ No |
chore | Maintenance | chore: update deps | ❌ No |
ci | CI/CD | ci: add build cache | ❌ No |
build | Build system | build: update webpack | ❌ No |
revert | Revert commit | revert: feat: add feature | ✅ Patch |
Commit examples
# 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"# 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"# 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"# 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 --continue2. 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 types3. Push your branch:
# First push
git push -u origin feature/my-feature
# Subsequent pushes
git pushCreating the PR
# 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"# Push and visit:
# https://github.com/OneDigital-Product/monorepo/pull/new/feature/my-featurePR 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
anytypes 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
anytypes
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-merge2. 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 labels —
priority: highmerges first - Dependencies — Dependent PRs merge in order
Priority labels:
priority: high— Security fixes, critical bugspriority: normal— Features, regular fixes (default)priority: low— Refactoring, documentation
Changesets
For changes that should trigger releases, create a changeset.
When to create changesets
| Change Type | Changeset? | Version Bump |
|---|---|---|
| New features | ✅ Yes | Minor (0.X.0) |
| Bug fixes | ✅ Yes | Patch (0.0.X) |
| Breaking changes | ✅ Yes | Major (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
---
"@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---
"@repo/auth": major
---
BREAKING: Redesign authentication API
- Changed auth endpoints to require Bearer tokens
- Removed deprecated `apiKey` parameter
- See migration guide: /docs/migration/auth-v2Next steps
- Learn conventions: Coding Conventions →
- Handle errors: Error Handling →
- Create packages: Creating Packages →
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-leaseInteractive 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 typoCherry-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 abc123Stashing 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 abc123Amending 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-leaseAmend 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 --allCommit 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-featureWrong commit message
# If not pushed yet
git commit --amend -m "correct message"
# If already pushed
git revert abc123 # Better to create new commitLost commits
# Find lost commits
git reflog
# Restore lost commit
git checkout <commit-hash>
git checkout -b recovered-workLarge 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 -- --allMerge 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 pushGitHub 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