Skip to content

05_17_06: Merge Strategies - AudioLab Integration Workflows

Executive Summary

Comprehensive merge strategies and conflict resolution for AudioLab development. Provides intelligent merge recommendations, automated conflict resolution, and guided workflows for all integration scenarios.

Key Features: - 5 merge strategies (fast-forward, merge commit, squash, rebase, cherry-pick) - Branch-specific merge policies - Automated conflict resolution - Intelligent strategy recommendation - Interactive conflict resolver - File-specific resolution strategies


Problem Statement

Without merge strategies: - ❌ Inconsistent merge practices - ❌ Messy git history - ❌ Time-consuming conflict resolution - ❌ Lost context in history - ❌ Difficult rollbacks

With merge strategies: - ✅ Consistent, predictable merges - ✅ Clean, readable history - ✅ Automated conflict resolution (70%+ of conflicts) - ✅ Preserved context and traceability - ✅ Easy feature rollback


Architecture

5 Merge Strategies

1. Fast-Forward Merge

git merge --ff-only feature/branch

When to use: - Target branch unchanged since branching - Pulling upstream updates - Simple hotfixes

Advantages: - Linear history - No merge commits - Clean timeline

Disadvantages: - Loses branch context - Cannot merge diverged branches


2. Merge Commit

git merge --no-ff feature/branch

When to use: - Feature branches → develop - Release branches → main - Preserving feature boundaries

Advantages: - Complete history preservation - Atomic rollback (revert merge commit) - Clear feature boundaries - Shows collaboration

Disadvantages: - More complex history graph - Extra merge commits


3. Squash Merge

git merge --squash feature/branch
git commit -m "feat(scope): comprehensive description"

When to use: - Many WIP commits - Experimental branches - External contributions needing cleanup

Advantages: - Clean, single commit per feature - Hides messy development - Easy to understand

Disadvantages: - Loses detailed history - Cannot cherry-pick individual commits - No authorship preservation


4. Rebase Merge

git rebase develop
git push --force-with-lease

When to use: - Personal feature branches - Cleaning up before PR - Creating linear history

⚠️ GOLDEN RULE: Never rebase shared branches

Safe: - Personal feature branches - Before creating PR - With explicit team agreement

DANGEROUS: - main branch (NEVER) - develop branch (NEVER) - Shared feature branches (avoid)


5. Cherry-Pick

git cherry-pick abc123

When to use: - Backporting fixes to release branches - Hotfixes across branches - Selective feature porting

Example:

# Fix in develop: abc123
git checkout release/v2.0
git cherry-pick abc123
git push origin release/v2.0
# Deploy hotfix v2.0.1


Branch-Specific Strategies

Main Branch

Allowed sources: release/*, hotfix/* Default strategy: Merge commit Always: --no-ff, signed commits, tags

git checkout main
git pull origin main
git merge --no-ff --verify-signatures release/v2.1.0
git tag -a v2.1.0 -m "Release v2.1.0"
git push origin main --tags

Requirements: - All tests passing - Documentation updated - Changelog updated - Version bumped - Code signed


Develop Branch

Allowed sources: feature/*, bugfix/*, refactor/* Default strategy: Merge commit Always: --no-ff, delete branch after merge

git checkout develop
git pull origin develop
git merge --no-ff feature/new-atom
git push origin develop
git branch -d feature/new-atom
git push origin --delete feature/new-atom

Feature Branches

Parent: develop Update strategy: Rebase Merge strategy: Merge commit (or squash if >10 poor commits)

Regular updates:

git checkout feature/my-feature
git fetch origin
git rebase origin/develop


Release Branches

Parent: develop Targets: main + develop Strategy: Merge commit with tags

# Merge to main
git checkout main
git merge --no-ff release/v2.1.0
git tag -a v2.1.0 -m "Release v2.1.0"

# Merge back to develop
git checkout develop
git merge --no-ff release/v2.1.0

# Cleanup
git branch -d release/v2.1.0
git push origin main develop --tags
git push origin --delete release/v2.1.0

Hotfix Branches

Parent: main Targets: main + develop Strategy: Merge commit, bump patch version

# Create hotfix
git checkout -b hotfix/v2.0.1 main
# ... fix ...
git commit -m "fix: critical audio processing bug"

# Merge to main
git checkout main
git merge --no-ff hotfix/v2.0.1
git tag -a v2.0.1 -m "Hotfix v2.0.1"

# Merge to develop
git checkout develop
git merge --no-ff hotfix/v2.0.1

# Cleanup
git branch -d hotfix/v2.0.1
git push origin main develop --tags

Conflict Resolution

Conflict Types

Detected by:

git status  # Shows "both modified", "both added", etc.

Conflict markers:

<<<<<<< HEAD (current branch)
float gain = 0.5f;
======= (separator)
float gain = 0.7f;
>>>>>>> feature/volume-control (incoming)


Resolution Strategies

1. Manual Resolution

Workflow: 1. Open file, locate conflict markers 2. Choose resolution: - Accept current (HEAD) - Accept incoming (branch) - Accept both (combine) - Reject both (new solution) 3. Remove conflict markers 4. Stage file: git add file.cpp 5. Continue: git merge --continue


2. Ours/Theirs

Accept one side entirely:

# Keep current version (ours)
git checkout --ours package-lock.json
git add package-lock.json

# Accept incoming version (theirs)
git checkout --theirs README.md
git add README.md

Auto-resolve during merge:

# Favor current branch for conflicts
git merge -X ours feature/branch

# Favor incoming branch for conflicts
git merge -X theirs feature/branch


3. Tool-Assisted

Configure merge tool:

# VS Code
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'

# KDiff3
git config --global merge.tool kdiff3

Use:

git mergetool  # Opens configured tool for each conflict


4. File-Specific Strategies

Lock files: Regenerate

git checkout --ours audiolab-lock.yaml
python dependency_resolver.py lock
git add audiolab-lock.yaml

Generated files: Rebuild

rm *.generated.cpp
# Run build to regenerate
git add *.generated.cpp

Binary files: Choose one

git checkout --ours image.png  # Or --theirs
git add image.png


Tools

merge_advisor.py

Analyzes branches and recommends merge strategies.

Usage:

# Analyze current branch for merge to develop
python merge_advisor.py analyze

# Get merge recommendation
python merge_advisor.py recommend --source feature/my-work --target develop

# Check for conflicts
python merge_advisor.py conflicts --source feature/my-work --target develop

Example output:

============================================================
Merge Strategy Recommendation
============================================================

Recommended Strategy: merge_commit
Confidence:           90%

Reasoning:
  • Feature branch with quality commits
  • Preserves development history
  • Enables feature rollback

Command:
  git merge --no-ff feature/my-work

⚠️  Potential Conflicts Detected

Conflicting files (3):
  • src/dsp/processor.cpp
  • include/audio/buffer.h
  • CMakeLists.txt


conflict_resolver.py

Automated and interactive conflict resolution.

Commands:

List conflicts

python conflict_resolver.py list

Output:

============================================================
Conflicting Files (5)
============================================================

🤖 audiolab-lock.yaml
   Strategy: regenerate
   Markers:  1

👤 src/processor.cpp
   Strategy: manual
   Markers:  3

🤖 build/generated.cpp
   Strategy: rebuild
   Markers:  0

Auto-resolve

python conflict_resolver.py auto

Resolves: - Lock files (regenerate) - Generated files (rebuild) - Binary files (choose one) - Simple conflicts (one side empty, both identical)

Result:

Resolving audiolab-lock.yaml using regenerate...
  ✓ Resolved
Resolving build/generated.cpp using rebuild...
  ✓ Resolved

============================================================
Summary
============================================================
✓ Resolved: 3
✗ Failed:   0

Interactive resolution

python conflict_resolver.py interactive

Guides through each conflict with options: 1. Use suggested strategy 2. Take ours 3. Take theirs 4. Manual resolution 5. Skip q. Quit

Resolve specific file

python conflict_resolver.py resolve --file src/processor.cpp --strategy ours

Configuration Files

merge_strategies.yaml

Complete merge strategy configuration: - 5 strategy definitions - Branch-specific rules - Conflict resolution policies - Merge commit templates - Protected branch settings - Best practices

Size: ~21 KB


Common Scenarios

Scenario 1: Feature Branch with Clean History

Context: Feature branch, 5 commits, good messages, no conflicts

Recommendation: Merge commit

git checkout develop
git merge --no-ff feature/new-filter


Scenario 2: Feature Branch with Messy History

Context: 15 commits, many "WIP", "fix typo", etc.

Recommendation: Squash merge

git checkout develop
git merge --squash feature/experimental
git commit -m "feat(dsp): implement adaptive filter with CPU optimization"


Scenario 3: Hotfix Needed Across Branches

Context: Critical bug in develop, need in release/v2.0

Recommendation: Cherry-pick

# Fix in develop: commit abc123
git checkout release/v2.0
git cherry-pick abc123
git push origin release/v2.0


Scenario 4: Lock File Conflict

Context: audiolab-lock.yaml conflicts

Recommendation: Regenerate

git checkout --ours audiolab-lock.yaml
python dependency_resolver.py lock
git add audiolab-lock.yaml
git merge --continue


Scenario 5: Same Line Modified Both Sides

Context: Both branches modified same line

Manual resolution required: 1. Understand intent of both changes 2. Combine intelligently or choose best 3. Test result

Example:

// Branch A: float gain = 0.7f;  (increased volume)
// Branch B: float gain = 0.3f;  (decreased volume)
// Resolution: Choose based on requirements


Workflow Integration

With Pull Requests

# .github/workflows/pr-check.yml
- name: Check merge strategy
  run: python merge_advisor.py recommend --source ${{ github.head_ref }}

- name: Check for conflicts
  run: python merge_advisor.py conflicts --source ${{ github.head_ref }}

With CI/CD

# .github/workflows/merge.yml
- name: Auto-resolve conflicts
  run: python conflict_resolver.py auto

- name: Verify no conflicts remain
  run: |
    if git diff --check; then
      echo "✓ All conflicts resolved"
    else
      echo "✗ Manual resolution needed"
      exit 1
    fi

Pre-merge Checklist

Before merging to main: - [ ] All tests passing - [ ] Code reviewed and approved - [ ] Documentation updated - [ ] Changelog entry added - [ ] Version bumped - [ ] No merge conflicts - [ ] Commits signed - [ ] Branch up-to-date with target


Best Practices

General

  1. Merge frequently - Avoid large conflicts
  2. Keep feature branches short - <2 weeks ideal
  3. Update regularly - Merge develop → feature often
  4. Test before merging - All tests must pass
  5. Descriptive messages - Explain what and why

Conflict Prevention

  1. Communicate - Coordinate overlapping work
  2. Use feature flags - For large changes
  3. Separate refactoring - Don't mix with features
  4. Coordinate renames - Plan file moves
  5. Regenerate lock files - Don't merge them

Strategy Selection

  1. Merge commit for features - Preserves history
  2. Squash for messy branches - Cleans history
  3. Fast-forward for updates - When possible
  4. Never rebase shared branches - Creates duplicates
  5. Cherry-pick for hotfixes - Across branches

Conflict Resolution

  1. Understand both sides - Before resolving
  2. Test after resolution - Always verify
  3. Ask original authors - When unclear
  4. Document complex cases - In commit message
  5. Use merge tools - For complex conflicts

Metrics & Monitoring

Tracked Metrics

  • Merge frequency (target: daily)
  • Conflict rate (target: <20%)
  • Time to resolve conflicts
  • Merge commit reversion rate
  • Branch lifetime (target: <2 weeks)

Alerts

Branch >2 weeks old:

Action: Notify owner to merge or update

Conflict rate >20%:

Action: Review merge strategy, increase communication

Large merge (>1000 lines):

Action: Require additional review


Protected Branch Rules

Main Branch

  • Require pull request
  • Require 2 approvals
  • Require passing CI
  • Require signed commits
  • No force push
  • No direct push

Develop Branch

  • Require pull request
  • Require 1 approval
  • Require passing tests
  • No force push

Troubleshooting

"Not possible to fast-forward"

Cause: Target branch has diverged

Solution:

# Use merge commit instead
git merge --no-ff feature/branch


Merge conflict in binary file

Cause: Cannot merge binary files

Solution:

# Choose one version
git checkout --ours image.png  # Or --theirs
git add image.png


Lost commits after rebase

Cause: Rebased shared branch

Solution:

# Find lost commits
git reflog

# Recover
git reset --hard HEAD@{5}  # Or appropriate reflog entry


Merge created duplicate commits

Cause: Rebased commits that were already in target

Solution: Prevention: Never rebase shared branches


Cannot resolve semantic conflict

Cause: No text conflict, but logic incompatible

Example: - Branch A: Adds call to function foo() - Branch B: Removes function foo() - No text conflict, but won't compile

Solution: - Comprehensive test suite (catches at CI) - Code review (catches during review)


Platform-Specific Notes

Windows

  • Use Git Bash or WSL for commands
  • Set core.autocrlf = true for line endings

macOS

  • Native git support
  • Consider GitX or SourceTree for visualization

Linux

  • Native git support
  • Use tig or gitk for history visualization

Quick Reference

# Recommend strategy
python merge_advisor.py recommend

# List conflicts
python conflict_resolver.py list

# Auto-resolve
python conflict_resolver.py auto

# Interactive resolution
python conflict_resolver.py interactive

# Merge with strategy
git merge --no-ff feature/branch      # Merge commit
git merge --squash feature/branch     # Squash
git merge --ff-only feature/branch    # Fast-forward
git rebase develop                    # Rebase

# Conflict resolution
git checkout --ours file.cpp          # Take ours
git checkout --theirs file.cpp        # Take theirs
git mergetool                         # Launch merge tool
git merge --continue                  # Continue after resolution
git merge --abort                     # Abort merge

Part of AudioLab Version Control System (05_17_VERSION_CONTROL)