Skip to main content

Branch Strategy

Branch Strategy

Overview

The edge-ai project uses a dual-branch strategy with dev and main branches to separate active development from production-ready releases.

Quick Reference

TaskAction
Daily workBranch from dev, PR to dev
ReleasesAutomated from devmain (review and merge PR)
HotfixesBranch from main, release → auto-syncs to dev
Sync checkgit log origin/main..origin/dev (empty = in sync)

Branch Roles

BranchPurposeUpdatesProtection
devActive developmentFeature/fix PRs1 approval required, CI required, automation can force-push
mainProduction releasesRelease PRs only2 approvals required, CI required, linear history, no force-push

Development and Release Cycle

graph LR
A[Feature Branch] -->|PR| B[dev]
B -->|Release Workflow| C[release/vX.Y.Z]
C -->|PR| D[main]
D -->|Intelligent Sync| B

Standard Workflow:

  1. Create feature branch from dev
  2. Create PR to dev, review, and merge
  3. When ready for release, run release workflow (automated)
  4. Review and merge release PR to main
  5. dev automatically synced from main (strategy auto-selected)

Hotfix Workflow:

  1. Branch from main (e.g., hotfix/critical-bug)
  2. Apply minimal fix, trigger hotfix release (bumps PATCH version)
  3. Fast-track release PR review and merge to main
  4. Automatic sync brings hotfix to dev

Branch Synchronization

Automatic Triggers:

  • Post-Release: After release PR merged to main
  • Scheduled: Daily at 03:00 UTC

Intelligent Strategy Selection:

The sync automatically chooses between force-push or merge based on dev state:

#!/bin/bash
# Intelligent sync: main to dev

git fetch origin main dev
UNRELEASED=$(git log origin/main..origin/dev --oneline)

if [ -z "$UNRELEASED" ]; then
# Post-release: Clean slate
git push origin main:dev --force-with-lease
else
# Mid-cycle: Preserve unreleased work
git checkout dev
git merge origin/main --no-ff -m "chore: integrate external contributions from main"
git push origin dev
fi

Strategy Selection:

flowchart TD
Start([Sync Triggered]) --> Check{git log<br/>main..dev<br/>empty?}
Check -->|Yes| FP[Force-Push<br/>Clean slate]
Check -->|No| Merge[Merge<br/>Preserve unreleased work]
FP --> Done([✓ Complete])
Merge --> Done

Manual Sync (when automation unavailable):

# Force-push (post-release only)
git fetch origin main dev
[ -z "$(git log origin/main..origin/dev --oneline)" ] && \
git push origin main:dev --force-with-lease || \
echo "ERROR: dev has unreleased commits"

# Merge (mid-cycle with unreleased commits)
git checkout dev && git pull
git merge origin/main --no-ff -m "chore: integrate external contributions"
git push origin dev

Branch Protection

Settingdevmain
PR Approvals1 required2 required
CI ChecksRequiredRequired + security scan
Force PushAutomation onlyBlocked
Direct PushBlocked (except automation)Blocked
Linear HistoryNoYes
Work Item LinkOptionalRequired (Azure DevOps)
Code OwnersOptionalRequired

Full configuration files: GitHub · Azure DevOps

Common Scenarios

Feature or Bug Fix:

git checkout dev && git pull
git checkout -b feature/my-feature # or fix/my-bug
# Make changes, commit
git push origin feature/my-feature
# Create PR to 'dev' branch

Release:

  1. Run release workflow from dev
  2. Review auto-generated release PR
  3. Merge to maindev auto-syncs

Hotfix:

git checkout main && git pull
git checkout -b hotfix/critical-fix
# Apply minimal fix, commit
# Trigger hotfix release (bumps patch version)
# Fast-track PR to main → dev auto-syncs

Best Practices

Contributors:

  • Always branch from dev, never from main
  • Target all PRs to dev
  • Use conventional commits (feat, fix, docs, chore)
  • Keep feature branches updated with dev

Maintainers:

  • Release regularly to prevent dev drift
  • Monitor sync logs after releases
  • Validate version numbers in release PRs
  • Review breaking changes documentation

Troubleshooting

IssueSolution
Sync workflow failsCheck logs for permission/network issues; retry or sync manually
Merge conflicts in release PRVerify sync completed; resolve in release branch
Accidentally committed to mainBranch protection prevents this; if bypassed, PR commit to dev and reset main
Check if branches in syncgit log origin/main..origin/dev (empty = synced)

See Release Workflow Troubleshooting for detailed guidance.

FAQ

Why force-push after release instead of merge? Ensures dev and main are identical, preventing drift. Safe because all dev changes are already in the merged release.

Can I work on multiple features simultaneously? Yes, create separate feature branches from dev and merge independently.

Can I delete feature branches after merging? Yes, enable auto-delete in GitHub/Azure DevOps settings.

Can I create a release from a feature branch? No, releases must come from dev. Merge your feature first.


References


🤖 Crafted with precision by ✨Copilot following brilliant human instruction, then carefully refined by our team of discerning human reviewers.