Author: callinj
Name: Joe Callin
Title: Sr. Salesforce Developer
Email: joe@jcallin.dev

Overview

This document defines the Git branching and merge strategy for the Salesforce component library repository. The strategy optimizes for:

  • Clean history in dev/qa (multiple merges per day)
  • Full audit trail in main (production)
  • Minimal conflicts through proper promotion branch usage
  • Code review via Pull Requests for QA and Prod
  • Fast direct merges for Dev (multiple times per day)

Environment Branches

The repository maintains three primary environment branches:

  • dev - Development environment (multiple deployments per day)
  • qa - QA/Testing environment (multiple deployments per day)
  • main - Production environment (daily or weekly deployments)

Note: The branch is named main (following Git conventions), but it maps to and deploys to the production environment. In all Git commands and branch references, use main. When referring to environments or deployments, main represents production.

Branch Types

Feature Branches

Feature branches are created for new development work tied to user stories.

Naming Convention: feature/STORY-123-description

  • Story number is required
  • Short description is required (kebab-case)
  • Examples:
    • feature/STORY-123-add-user-authentication
    • feature/STORY-456-fix-login-bug
    • feature/STORY-789-implement-search-functionality

Hotfix Branches

Hotfix branches are created for critical bug fixes that need immediate deployment.

Naming Convention: hotfix/STORY-123-description

  • Story number is required
  • Short description is required (kebab-case)
  • Examples:
    • hotfix/STORY-789-critical-security-patch
    • hotfix/STORY-101-fix-payment-error
    • hotfix/STORY-202-resolve-data-loss-issue

Promotion Branches

Promotion branches are temporary branches created to promote features/hotfixes to environment branches. They allow for conflict resolution and testing before merging to the target environment.

Naming Convention: promotion/{env}-{story} or promotion/{env}-{story1}-{story2}

  • Environment prefix: dev, qa, or prod
  • Story numbers only (no descriptions) for brevity
  • Can contain multiple story numbers for multi-feature promotions
  • Examples:
    • promotion/dev-123
    • promotion/qa-123-456
    • promotion/prod-123
    • promotion/prod-hotfix-123

Why Use Promotion Branches?

Promotion branches provide several key benefits over merging feature branches directly into environment branches:

1. Conflict Resolution Isolation

  • Conflicts are resolved in the promotion branch, not the feature branch
  • Keeps feature branch history clean and focused on feature development
  • Allows testing of conflict resolutions before merging to environment
  • Multiple developers can resolve conflicts without affecting each other's feature branches

2. Multi-Feature Coordination

  • Multiple features can be merged into a single promotion branch
  • Enables testing features together before promoting to environment
  • Simplifies coordination when features depend on each other
  • Single promotion commit represents multiple related features

3. Environment State Management

  • Promotion branch is created from the target environment branch
  • Ensures promotion is based on latest environment state
  • Prevents promoting code that conflicts with recent environment changes
  • Makes it clear what state the environment was in when promotion was created

4. Testing and Validation

  • Promotion branch can be tested independently before merging
  • Allows validation of conflict resolutions
  • Enables integration testing of multiple features together
  • Provides safety net before code reaches environment branch

5. Clean Environment History

  • Environment branches maintain clean, readable history
  • Each promotion represents a logical unit of work
  • Easier to identify what was deployed and when
  • Simplifies rollback and troubleshooting

Alternative Without Promotion Branches:

Without promotion branches, merging feature branches directly to environment branches would:

  • Require resolving conflicts in feature branches (pollutes feature history)
  • Make it harder to coordinate multiple features
  • Risk promoting code that conflicts with recent environment changes
  • Create messy environment branch history with many small commits

Merge Strategy by Branch Type

1. Feature/Hotfix → Promotion Branch

Strategy: Normal Merge

  • Preserves commit history for code review
  • Easier conflict resolution (can resolve in promotion branch)
  • Allows multiple features to merge into same promotion branch cleanly
  • No force push required

Command:

git checkout promotion/dev-123
git merge feature/STORY-123-add-user-authentication --no-ff

2. Promotion Branch → Dev

Strategy: Squash Merge (Direct Merge)

  • Creates single commit per promotion (clean history)
  • Fast merges for multiple deployments per day
  • Easy to identify what was deployed when
  • Can still see individual commits in promotion branch if needed
  • No PR required - direct merge for speed

Command:

git checkout dev
git merge promotion/dev-123 --squash
git commit -m "Promote STORY-123 to dev"
git push origin dev

3. Promotion Branch → QA

Strategy: Normal Merge (via Pull Request)

  • Preserves commit history for code review and audit trail
  • Requires Pull Request for code review and approval
  • PR provides visibility and approval workflow
  • Merge via PR interface (normal merge option)

Workflow:

  1. Push promotion branch to remote
  2. Create PR: promotion/qa-123qa
  3. Review and approve PR
  4. Merge PR using normal merge option in PR interface

4. Promotion Branch → Main (Production)

Strategy: Normal Merge (via Pull Request)

  • Preserves full commit history for audit/compliance
  • Maintains traceability to original feature branches
  • Requires Pull Request for code review and approval
  • Less frequent merges (daily/weekly) so merge commits are acceptable
  • Merge via PR interface (normal merge option)

Workflow:

  1. Push promotion branch to remote
  2. Create PR: promotion/prod-123main
  3. Review and approve PR
  4. Merge PR using normal merge option in PR interface

Pull Request Best Practices

PR Title Format

  • Use descriptive titles: Promote STORY-123 to qa or Promote STORY-123 and STORY-456 to prod
  • Include story numbers in title for traceability

PR Description Template

## Summary
Promoting STORY-123 to [qa/prod]

## Changes
- Feature X implementation
- Bug fix Y

## Testing
- [ ] Unit tests passing
- [ ] Integration tests passing
- [ ] Manual testing completed

## Related
- Story: STORY-123
- Dependencies: STORY-456 (if applicable)

PR Merge Options

For QA PRs:

  • Use Create a merge commit option (normal merge)
  • Preserves commit history for code review and audit trail
  • Maintains traceability to original feature branches

For Prod PRs (merging to main branch):

  • Use Create a merge commit option (normal merge)
  • Preserves full commit history
  • Maintains audit trail

Never use:

  • Rebase and merge (rewrites history, not suitable for promotion branches)

Promotion Branch Workflow

Creating Promotion Branches

  1. From target environment branch:

    git checkout dev
    git pull origin dev
    git checkout -b promotion/dev-123
  2. Merge feature(s) into promotion:

    git merge feature/STORY-123-add-user-authentication --no-ff
    # Resolve conflicts here if any
  3. Test promotion branch (before merging to environment)

  4. Merge promotion to environment:

    For Dev (Direct Merge):

    git push origin promotion/dev-123
    git checkout dev
    git merge promotion/dev-123 --squash
    git commit -m "Promote STORY-123 to dev"
    git push origin dev

    For QA (via Pull Request):

    git push origin promotion/qa-123
    # Create PR: promotion/qa-123 → qa
    # Review and approve PR
    # Merge PR using normal merge option

    For Prod (via Pull Request, merges to main branch):

    git push origin promotion/prod-123
    # Create PR: promotion/prod-123 → main
    # Review and approve PR
    # Merge PR using normal merge option

Multi-Feature Promotion Branches

When multiple features need to go together:

For Dev:

git checkout -b promotion/dev-123-456
git merge feature/STORY-123-add-user-authentication --no-ff
git merge feature/STORY-456-fix-login-bug --no-ff
# Resolve any conflicts
# Test combined features
git push origin promotion/dev-123-456
git checkout dev
git merge promotion/dev-123-456 --squash
git commit -m "Promote STORY-123 and STORY-456 to dev"
git push origin dev

For QA/Prod:

# For QA
git checkout -b promotion/qa-123-456
git merge feature/STORY-123-add-user-authentication --no-ff
git merge feature/STORY-456-fix-login-bug --no-ff
# Resolve any conflicts
# Test combined features
git push origin promotion/qa-123-456
# Create PR: promotion/qa-123-456 → qa
# Review and approve PR
# Merge PR using normal merge option

# For Prod (merges to main branch)
git checkout -b promotion/prod-123-456
git merge feature/STORY-123-add-user-authentication --no-ff
git merge feature/STORY-456-fix-login-bug --no-ff
# Resolve any conflicts
# Test combined features
git push origin promotion/prod-123-456
# Create PR: promotion/prod-123-456 → main
# Review and approve PR
# Merge PR using normal merge option

Branch Syncing Strategy

Forward Sync (After Major Releases)

Sync branches forward to keep them aligned:

Main (Prod) → QA → Dev

  1. Sync QA from Main (Prod):

    git checkout qa
    git pull origin qa
    git merge main --no-ff
    # Resolve conflicts
    git push origin qa
  2. Sync Dev from QA:

    git checkout dev
    git pull origin dev
    git merge qa --no-ff
    # Resolve conflicts
    git push origin dev

When to Sync

  • After major releases to main (production)
  • After completing a phase/sprint
  • Before starting new feature work
  • When branches drift significantly

Conflict Resolution During Sync

  • Resolve conflicts in the target branch (qa or dev)
  • Create a sync commit: git commit -m "Sync qa with main"
  • Test after sync before continuing feature work

Workflow Diagram

feature/STORY-123-add-user-authentication
    ↓ (normal merge)
promotion/dev-123 ───→ dev (squash merge, direct)
promotion/qa-123 ────→ qa (normal merge, via PR)
promotion/prod-123 ──→ main (normal merge, via PR)

dev ────────────────┐
                    │ (normal merge, periodic sync)
                    ↓
main ───────────────┘
                    ↑ (normal merge, periodic sync)
qa ─────────────────┘

Handling Hotfixes

Hotfixes follow same pattern but may skip environments:

# Hotfix to prod (merges to main branch via PR)
git checkout main
git pull origin main
git checkout -b promotion/prod-hotfix-123
git merge hotfix/STORY-123-critical-security-patch --no-ff
# Test
git push origin promotion/prod-hotfix-123
# Create PR: promotion/prod-hotfix-123 → main
# Review and approve PR (may expedite for hotfixes)
# Merge PR using normal merge option
git tag -a v1.2.1 -m "Hotfix STORY-123"

# Then backport to qa/dev (via PR for qa, direct for dev)
git checkout qa
git pull origin qa
git checkout -b promotion/qa-hotfix-123
git merge hotfix/STORY-123-critical-security-patch --no-ff
git push origin promotion/qa-hotfix-123
# Create PR: promotion/qa-hotfix-123 → qa
# Merge PR

# Dev can merge directly
git checkout dev
git merge hotfix/STORY-123-critical-security-patch --squash
git commit -m "Backport hotfix STORY-123 to dev"
git push origin dev

Best Practices

  1. Always create promotion branch from target environment branch

    • Ensures promotion branch is based on latest environment state
  2. Resolve conflicts in promotion branch, not feature branch

    • Keeps feature branch history clean
    • Allows testing of resolved conflicts before promotion
  3. Test promotion branch before merging to environment

    • Catch integration issues early
    • Verify conflict resolutions
  4. Use Pull Requests for QA and Prod

    • QA and Prod require PRs for code review and approval
    • Dev can use direct merge for speed (multiple times per day)
    • PRs provide visibility and audit trail for production
  5. Delete promotion branches after successful merge

    • Keeps branch list clean
    • Promotion branches are temporary by nature
    • PR interface can auto-delete branches after merge
  6. Use descriptive commit messages

    • For squash merges: "Promote STORY-123 to dev"
    • For sync merges: "Sync qa with main - Release 1.2.0"
  7. Tag main branch on releases

    • git tag -a v1.2.0 -m "Release 1.2.0"
    • Helps track what's in production

Summary

  • Feature → Promotion: Normal merge (preserves history)
  • Promotion → Dev: Squash merge, direct merge (fast, multiple per day)
  • Promotion → QA: Normal merge, via Pull Request (review required, preserves history)
  • Promotion → Prod (main branch): Normal merge, via Pull Request (review required, audit trail)
  • Sync: Normal merge (preserves sync history)
  • Conflicts: Resolve in promotion branch
  • Cleanup: Delete promotion branches after merge

This strategy balances clean history for frequent dev merges with full audit trail for QA and production, while minimizing conflicts through proper promotion branch usage. PRs provide necessary review gates for QA and Prod environments.


Change History

Version 1.1 - 2026-01-15

  • Updated QA merge strategy from squash merge to normal merge
  • QA merges now preserve commit history for better audit trail

Version 1.0 - 2026-01-14

  • Initial release of Git branching and merge strategy documentation

Last Updated: 2026-01-15
Version: 1.1