Skip to content

Git Workflow & Branching Strategy

Git workflow guidelines for the MMR SaaS Platform.

Table of Contents


Branching Model

We use GitHub Flow with Release Branches - a simplified Git workflow that balances speed with stability.

Main Branches

main        ← Production-ready code (protected)
develop     ← Integration branch for features (protected)

Supporting Branches

feature/*   ← New features
bugfix/*    ← Bug fixes
hotfix/*    ← Production emergency fixes
release/*   ← Release preparation

Branch Diagram

main       ─┬────────────────┬──────────────────┬─────>
            │                │                  │
            │ hotfix/fix-auth│                  │ release/v2.1.0
            ├─┐              │                  ├─┐
            │ └──────────────┤                  │ │
            │                │                  │ └──────>
            │                │                  │
develop    ─┼────┬───────────┼──────────────────┼─────>
            │    │           │                  │
            │    │ feature/  │                  │
            │    │ products  │                  │
            │    ├─┐         │                  │
            │    │ └─────────┤                  │
            │    │           │                  │
            └────┴───────────┴──────────────────┘

Branch Types

1. main (Production)

Purpose: Reflects production-ready code

Protection Rules: - ✅ Require pull request reviews (2 approvers) - ✅ Require status checks to pass - ✅ Require branches to be up to date - ✅ No direct commits allowed - ✅ Only release/* and hotfix/* can merge

Deploy: Automatically deploys to production

2. develop (Integration)

Purpose: Integration branch for active development

Protection Rules: - ✅ Require pull request reviews (1 approver) - ✅ Require status checks to pass - ✅ No direct commits allowed - ✅ feature/, bugfix/ branches merge here

Deploy: Automatically deploys to staging

3. feature/* (New Features)

Purpose: Develop new features

Lifetime: Create from develop, merge back to develop

Example Names:

feature/user-authentication
feature/product-crud
feature/payment-integration
feature/dashboard-redesign

Workflow:

# Create feature branch
git checkout develop
git pull origin develop
git checkout -b feature/product-catalog

# Work on feature
git add .
git commit -m "feat: add product catalog module"

# Push and create PR
git push origin feature/product-catalog
# Open PR: feature/product-catalog → develop

4. bugfix/* (Bug Fixes)

Purpose: Fix bugs found in develop/staging

Lifetime: Create from develop, merge back to develop

Example Names:

bugfix/login-validation
bugfix/product-price-calculation
bugfix/session-timeout

Workflow:

git checkout develop
git pull origin develop
git checkout -b bugfix/fix-login-redirect

# Fix bug
git add .
git commit -m "fix: correct login redirect after auth"

# Push and create PR
git push origin bugfix/fix-login-redirect
# Open PR: bugfix/fix-login-redirect → develop

5. hotfix/* (Emergency Production Fixes)

Purpose: Critical fixes for production issues

Lifetime: Create from main, merge to both main and develop

Example Names:

hotfix/security-patch
hotfix/payment-error
hotfix/data-leak

Workflow:

# Create hotfix branch from main
git checkout main
git pull origin main
git checkout -b hotfix/fix-auth-bypass

# Fix critical issue
git add .
git commit -m "fix: patch authentication bypass vulnerability"

# Push and create PR to main
git push origin hotfix/fix-auth-bypass
# Open PR: hotfix/fix-auth-bypass → main

# After merging to main, also merge to develop
git checkout develop
git pull origin develop
git merge main
git push origin develop

6. release/* (Release Preparation)

Purpose: Prepare for production release (version bumps, changelog, final testing)

Lifetime: Create from develop, merge to main and develop

Example Names:

release/v2.0.0
release/v2.1.0

Workflow:

# Create release branch
git checkout develop
git pull origin develop
git checkout -b release/v2.1.0

# Update version in package.json
npm version 2.1.0

# Update CHANGELOG.md
# Final testing and bug fixes

# Commit release changes
git add .
git commit -m "chore: prepare release v2.1.0"

# Push and create PR to main
git push origin release/v2.1.0
# Open PR: release/v2.1.0 → main

# After merging to main, tag the release
git checkout main
git pull origin main
git tag -a v2.1.0 -m "Release version 2.1.0"
git push origin v2.1.0

# Merge back to develop
git checkout develop
git merge main
git push origin develop


Naming Conventions

Branch Names

Format: <type>/<short-description>

Rules: - Use lowercase with hyphens - Be descriptive but concise - No issue numbers in branch name (use PR description)

Examples:

 feature/user-dashboard
 bugfix/login-validation-error
 hotfix/security-patch-xss
 release/v2.0.0

 Feature/UserDashboard          (use lowercase)
 fix-bug                        (missing type prefix)
 feature/issue-123              (no issue numbers)
 feature/add_new_user_dashboard (use hyphens, not underscores)

Commit Messages

We follow Conventional Commits specification:

Format:

<type>(<scope>): <subject>

[optional body]

[optional footer]

Types: - feat: New feature - fix: Bug fix - docs: Documentation changes - style: Code style changes (formatting, semicolons, etc.) - refactor: Code refactoring - perf: Performance improvements - test: Adding or updating tests - chore: Maintenance tasks (dependencies, build config) - ci: CI/CD configuration changes - revert: Revert previous commit

Examples:

 feat: add user authentication module
 fix: resolve session timeout issue
 docs: update API documentation for products
 refactor: simplify tenant context logic
 test: add E2E tests for login flow
 chore: update dependencies to latest versions
 perf: optimize database queries for products
 ci: add automated deployment workflow

# With scope
 feat(auth): implement JWT refresh token rotation
 fix(products): correct price calculation logic
 test(users): add unit tests for user service

# With body
 feat: add multi-factor authentication

   Implement two-factor authentication using TOTP.
   Users can enable/disable 2FA in account settings.

   Closes #123

# Breaking change
 feat!: change user ID from UUID to integer

   BREAKING CHANGE: User IDs are now integers instead of UUIDs.
   This requires database migration.

Bad Examples:

 Added new feature                    (not descriptive, no type)
 Fixed bug                            (not descriptive)
 WIP                                  (work in progress - don't commit)
 feat: Added new user authentication  (use present tense: "add")
 Fix Login Bug                        (use lowercase, no type)


Development Workflow

1. Start New Feature

# Ensure develop is up to date
git checkout develop
git pull origin develop

# Create feature branch
git checkout -b feature/product-catalog

# Make changes
# ... code, code, code ...

# Stage changes
git add .

# Commit with conventional message
git commit -m "feat: add product catalog with CRUD operations"

# Push to remote
git push origin feature/product-catalog

2. Keep Branch Updated

# Update develop
git checkout develop
git pull origin develop

# Switch back to feature branch
git checkout feature/product-catalog

# Rebase on latest develop
git rebase develop

# Force push (if already pushed)
git push origin feature/product-catalog --force-with-lease

Note: Use --force-with-lease instead of --force to avoid accidentally overwriting others' work.

3. Create Pull Request

  1. Push your branch to GitHub
  2. Go to GitHub repository
  3. Click "Compare & pull request"
  4. Fill out PR template (see Pull Request Process)
  5. Request reviewers
  6. Address feedback

4. After PR is Merged

# Switch to develop
git checkout develop

# Pull latest (includes your merged changes)
git pull origin develop

# Delete local feature branch
git branch -d feature/product-catalog

# Delete remote feature branch (if not auto-deleted)
git push origin --delete feature/product-catalog

Pull Request Process

PR Title

Follow conventional commit format:

feat: add product catalog module
fix: resolve authentication timeout issue
docs: update deployment guide

PR Description Template

## Summary
Brief description of what this PR does (1-3 sentences)

## Type of Change
- [ ] New feature
- [ ] Bug fix
- [ ] Documentation update
- [ ] Refactoring
- [ ] Performance improvement
- [ ] Test improvements

## Changes Made
- Added Product entity with multi-tenant support
- Implemented CRUD endpoints
- Created unit and E2E tests
- Updated API documentation

## Testing
- [ ] All unit tests pass (`pnpm test`)
- [ ] All E2E tests pass (`pnpm test:e2e`)
- [ ] Manually tested with Postman
- [ ] Verified tenant isolation
- [ ] Tested in staging environment

## Database Changes
- [ ] No database changes
- [ ] Migration included (run `pnpm db:migrate`)
- [ ] Seed data updated

## Breaking Changes
- [ ] No breaking changes
- [ ] Breaking changes documented below

[If breaking changes, describe migration path]

## Checklist
- [ ] Code follows project conventions
- [ ] No linting errors (`pnpm lint`)
- [ ] No TypeScript errors (`pnpm type-check`)
- [ ] Documentation updated (if needed)
- [ ] Tests added/updated
- [ ] Commit messages follow conventional commits
- [ ] Branch is up to date with base branch

## Screenshots (if applicable)
[Add screenshots for UI changes]

## Related Issues
Closes #123
Relates to #456

Code Review Guidelines

For Authors

Before Requesting Review: - [ ] Self-review your own code - [ ] Run all tests locally - [ ] Check for console.log or debugging code - [ ] Ensure no secrets/credentials in code - [ ] Update documentation

During Review: - Respond to feedback promptly - Be open to suggestions - Ask for clarification if needed - Mark resolved conversations

For Reviewers

What to Check: - [ ] Code correctness and logic - [ ] Adherence to coding standards - [ ] Test coverage - [ ] Security vulnerabilities - [ ] Performance considerations - [ ] Error handling - [ ] Multi-tenant isolation (critical!) - [ ] Documentation quality

Review Checklist:

Code Quality: - [ ] Code is readable and maintainable - [ ] Functions are small and focused - [ ] Variable names are descriptive - [ ] No code duplication - [ ] Error handling is comprehensive

Security: - [ ] No SQL injection vulnerabilities - [ ] Input validation present - [ ] Authentication required where needed - [ ] Authorization checks in place - [ ] No hardcoded secrets

Multi-Tenancy: - [ ] Uses TenantScopedRepository (backend) - [ ] No direct Repository usage (backend) - [ ] Tenant context validated - [ ] Cross-tenant access prevented

Testing: - [ ] Unit tests cover main functionality - [ ] E2E tests for critical flows - [ ] Edge cases considered - [ ] Test names are descriptive

Documentation: - [ ] Complex logic is commented - [ ] API endpoints documented - [ ] README updated (if needed)

Feedback Format:

# Blocking (must fix before merge)
🔴 **Security:** This endpoint is missing authentication guard
🔴 **Bug:** Logic error in price calculation

# Non-blocking (nice to have)
🟡 **Suggestion:** Consider extracting this into a separate function
🟡 **Performance:** This query could be optimized

# Praise (positive feedback)
🟢 **Great:** Excellent test coverage!
🟢 **Nice:** Clear variable naming

Merge Strategies

Squash and Merge (Default): - Combines all commits into one - Clean, linear history - Use for feature/* and bugfix/* branches

Merge Commit: - Preserves all individual commits - Use for release/* branches - Use for hotfix/* branches

Rebase and Merge: - Replays commits on top of base branch - Use rarely, only for very clean commit history


Release Process

Version Numbering

We use Semantic Versioning (SemVer): MAJOR.MINOR.PATCH

  • MAJOR: Incompatible API changes (e.g., 1.0.0 → 2.0.0)
  • MINOR: New features, backward compatible (e.g., 2.0.0 → 2.1.0)
  • PATCH: Bug fixes, backward compatible (e.g., 2.1.0 → 2.1.1)

Release Checklist

  1. Create Release Branch:

    git checkout develop
    git pull origin develop
    git checkout -b release/v2.1.0
    

  2. Update Version:

    # Update package.json in all apps
    cd apps/backend && npm version 2.1.0
    cd apps/web && npm version 2.1.0
    cd ../..
    
    # Or use pnpm workspace
    pnpm -r version 2.1.0
    

  3. Update CHANGELOG.md:

    ## [2.1.0] - 2026-06-20
    
    ### Added
    - Product catalog module with CRUD operations
    - Multi-factor authentication support
    
    ### Changed
    - Improved session caching performance
    - Updated UI design for dashboard
    
    ### Fixed
    - Authentication timeout issue
    - Product price calculation bug
    
    ### Security
    - Patched XSS vulnerability in product names
    

  4. Final Testing:

    pnpm test          # All unit tests
    pnpm test:e2e      # All E2E tests
    pnpm lint          # Linting
    pnpm type-check    # Type checking
    pnpm build         # Production build
    

  5. Commit Release Changes:

    git add .
    git commit -m "chore: prepare release v2.1.0"
    git push origin release/v2.1.0
    

  6. Create PR to main:

  7. PR: release/v2.1.0 → main
  8. Get 2 approvals
  9. Merge using "Merge commit"

  10. Tag Release:

    git checkout main
    git pull origin main
    git tag -a v2.1.0 -m "Release version 2.1.0"
    git push origin v2.1.0
    

  11. Merge Back to develop:

    git checkout develop
    git pull origin develop
    git merge main
    git push origin develop
    

  12. Deploy to Production:

  13. CI/CD automatically deploys tagged release
  14. Monitor application logs
  15. Run smoke tests

  16. Delete Release Branch:

    git branch -d release/v2.1.0
    git push origin --delete release/v2.1.0
    


Hotfix Procedures

When to Use Hotfix

Use hotfix/* for: - Critical security vulnerabilities - Data loss bugs - Payment processing errors - Service outages - Authentication/authorization bypasses

Don't use hotfix/* for: - Minor UI bugs - Non-critical issues - Feature requests

Hotfix Workflow

  1. Create Hotfix Branch:

    git checkout main
    git pull origin main
    git checkout -b hotfix/fix-payment-error
    

  2. Fix Issue:

    # Make minimal changes to fix the issue
    git add .
    git commit -m "fix: resolve payment processing error"
    

  3. Test Thoroughly:

    pnpm test
    pnpm test:e2e
    # Manual testing
    

  4. Update Version (Patch):

    pnpm -r version patch  # 2.1.0 → 2.1.1
    

  5. Create PR to main:

    git push origin hotfix/fix-payment-error
    # PR: hotfix/fix-payment-error → main
    # Require immediate review (1 approver minimum)
    

  6. After Merge to main:

    # Tag hotfix release
    git checkout main
    git pull origin main
    git tag -a v2.1.1 -m "Hotfix: payment processing error"
    git push origin v2.1.1
    
    # Merge to develop
    git checkout develop
    git pull origin develop
    git merge main
    git push origin develop
    
    # Delete hotfix branch
    git branch -d hotfix/fix-payment-error
    git push origin --delete hotfix/fix-payment-error
    


CI/CD Integration

Automated Checks on PR

Every pull request triggers:

  1. Linting: pnpm lint
  2. Type Checking: pnpm type-check
  3. Unit Tests: pnpm test
  4. E2E Tests: pnpm test:e2e
  5. Build: pnpm build

Status: PR cannot be merged unless all checks pass ✅

Deployment Pipeline

develop branch
  → Merge to develop
  → CI: Run tests
  → ✅ Deploy to Staging
  → Manual testing

main branch
  → Merge to main
  → Tag release (v2.1.0)
  → CI: Run tests + build
  → ✅ Deploy to Production
  → Smoke tests

GitHub Actions Example

.github/workflows/ci.yml:

name: CI

on:
  pull_request:
    branches: [develop, main]
  push:
    branches: [develop, main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Lint
        run: pnpm lint

      - name: Type check
        run: pnpm type-check

      - name: Unit tests
        run: pnpm test

      - name: Build
        run: pnpm build

  e2e:
    runs-on: ubuntu-latest
    needs: test
    steps:
      - uses: actions/checkout@v3
      # ... E2E test steps

Best Practices

1. Commit Early and Often

# ✅ Good: Small, focused commits
git commit -m "feat: add product entity"
git commit -m "feat: add product service"
git commit -m "feat: add product controller"
git commit -m "test: add product E2E tests"

# ❌ Bad: One giant commit
git commit -m "feat: add entire product module"

2. Write Descriptive Commit Messages

# ✅ Good
git commit -m "fix: resolve authentication timeout by increasing session TTL to 1 hour"

# ❌ Bad
git commit -m "fix bug"

3. Pull Before Push

# Always pull latest changes before pushing
git pull origin develop
# Resolve conflicts if any
git push origin feature/my-feature

4. Rebase to Clean Up History

# Before creating PR, clean up commits
git rebase -i develop

# Squash "WIP" commits, fix typos in messages
# Result: Clean, logical commit history

5. Delete Merged Branches

# After PR is merged
git branch -d feature/my-feature
git push origin --delete feature/my-feature

6. Keep Branches Short-Lived

  • Feature branches should live for 1-3 days max
  • Bugfix branches should be merged same day
  • Long-lived branches cause merge conflicts

7. Use .gitignore Properly

Never commit: - node_modules/ - .env files (use .env.example) - Build artifacts (dist/, build/) - IDE settings (.vscode/, .idea/) - OS files (.DS_Store, Thumbs.db)

8. Review Your Own Code First

Before requesting review:

# View all changes
git diff develop...feature/my-feature

# Self-review on GitHub by creating draft PR


Common Scenarios

Handling Merge Conflicts

# Update your branch with latest develop
git checkout feature/my-feature
git pull origin develop

# Resolve conflicts in editor
# ... fix conflicts ...

# Mark as resolved
git add .
git commit -m "chore: resolve merge conflicts"
git push origin feature/my-feature

Reverting a Commit

# Revert last commit (creates new commit)
git revert HEAD
git push origin feature/my-feature

# Revert specific commit
git revert <commit-hash>
git push origin feature/my-feature

Cherry-Picking Commits

# Apply specific commit from another branch
git cherry-pick <commit-hash>
git push origin feature/my-feature

Stashing Changes

# Save uncommitted changes
git stash

# Switch branches
git checkout other-branch

# Come back
git checkout feature/my-feature

# Restore changes
git stash pop

Syncing Fork with Upstream

# Add upstream remote
git remote add upstream <original-repo-url>

# Fetch upstream
git fetch upstream

# Merge upstream/develop into your develop
git checkout develop
git merge upstream/develop
git push origin develop

Version: 2.0.0 | Last Updated: 2026-06-20