14 KiB
ADR-009: Git Branching Strategy
Status
Accepted
Context
StarPunk needs a git branching strategy that supports:
- Semantic versioning workflow - Moving from 0.x.y development through 1.0.0 stable release
- Single developer initially - Optimized for solo work but scalable to small teams
- Clean release history - Clear tags and versioning aligned with SemVer
- Hotfix capability - Ability to patch production releases
- Minimal complexity - Appropriate for indie project scale
- Development discipline - Structure without bureaucracy
Current State
The project just renamed its primary branch from master to main to align with modern Git conventions and industry best practices. This is a brand new repository with no commits yet, currently at version 0.1.0 (development phase).
Requirements
The branching strategy must:
- Support semantic versioning releases (0.1.0 → 1.0.0 → 1.0.1 → 1.1.0 → 2.0.0)
- Work for solo and team development
- Enable clean releases with proper tagging
- Allow hotfixes to production versions
- Keep main branch stable - always in working state
- Minimize long-lived branches - integrate frequently
- Align with IndieWeb values - simplicity, no lock-in
- Be well-documented - clear workflows for common scenarios
Decision
We will adopt a simplified trunk-based development strategy with feature branches and semantic versioning integration.
Core Principles
- Single primary branch:
main - Branch name:
main(notmaster) - Feature branches: Short-lived branches for features/fixes
- Direct tagging: Tag
mainfor releases - Hotfix branches: For production patches (post-1.0.0)
- No long-lived branches: Integrate to main frequently
- Annotated tags: Always use annotated tags for releases
Branch Structure
Primary branch: main
- Single source of truth
- Always stable (tests pass)
- Tagged for releases
- Protected from force push
- Never rewritten
Feature branches: feature/<description> or <description>
- Branch from
main - Merge into
main - Short-lived (hours to days, not weeks)
- Deleted after merge
Fix branches: fix/<description> or bugfix/<description>
- Branch from
main - Merge into
main - Deleted after merge
Hotfix branches: hotfix/<version>-<description> (post-1.0.0 only)
- Branch from release tag (e.g.,
v1.0.0) - Fix critical production bugs
- Tagged as new patch release (e.g.,
v1.0.1) - Merged into
main - Deleted after release
Release branches: release/<version> (optional, rarely used)
- Only if release preparation requires multiple commits
- For V1, likely unnecessary (prepare on
mainor feature branch) - Branch from
main, merge back tomain, tag, delete
Branch Naming Conventions
Preferred format: <type>/<description>
Types:
feature/- New featuresfix/orbugfix/- Bug fixeshotfix/- Production hotfixesdocs/- Documentation onlyrefactor/- Code refactoringtest/- Test additionschore/- Maintenance tasks
Description:
- Lowercase with hyphens
- Descriptive but concise
- Example:
feature/micropub-endpoint,fix/rss-timezone
Alternative: Simple description without prefix (e.g., micropub-endpoint)
Tagging Strategy
Format: vMAJOR.MINOR.PATCH[-PRERELEASE]
Type: Annotated tags (always)
Examples:
v0.1.0- Development releasev1.0.0- First stable releasev1.0.1- Patch releasev1.0.0-alpha.1- Pre-release
Tag message format:
Release MAJOR.MINOR.PATCH: <Brief description>
[Optional details]
Workflows
Development (0.x.y):
- Work on
mainor feature branches - Commit frequently
- Tag development milestones (v0.1.0, v0.2.0)
- Breaking changes allowed
Stable releases (1.0.0+):
- Prepare release on
main - Update version and changelog
- Commit version bump
- Create annotated tag
- Push main and tag
Hotfixes (post-1.0.0):
- Branch from release tag
- Fix bug
- Update version and changelog
- Tag new patch version
- Merge to
main - Push main and tag
- Delete hotfix branch
Rationale
Why Simplified Trunk-Based Development?
Trunk-based development means developers integrate to a single branch (main) frequently, using short-lived feature branches.
Pros:
- Simple - One primary branch, minimal overhead
- Scalable - Works for solo and small teams
- Fast integration - Reduces merge conflicts
- Always releasable - Main stays stable
- Aligns with CI/CD - Easy to automate testing
- Reduces complexity - No long-lived branches to manage
Fits StarPunk because:
- Personal project optimized for simplicity
- Small codebase, infrequent releases
- Solo developer initially
- No need for complex branching
Why Main Instead of Master?
Decision: Use main as primary branch name
Rationale:
- Industry standard - GitHub, GitLab default since 2020
- Inclusive language - Removes potentially offensive terminology
- Aligns with modern practices - Most new projects use
main - Clear semantics - "Main" clearly indicates primary branch
- No functional difference - Just a name, but better name
Migration:
- Project just renamed
master→main - All documentation uses
mainconsistently
Why Not Git Flow?
Git Flow is a popular branching model with main, develop, release, hotfix, and feature branches.
Considered but rejected:
Pros:
- Well-defined process
- Clear separation of development and production
- Structured release process
Cons:
- Too complex for indie project
- Overhead - Multiple long-lived branches
- Slow integration - Features merge to develop, not main
- Designed for scheduled releases, not continuous delivery
- Overkill for single developer
Conclusion: Git Flow's complexity doesn't justify benefits for StarPunk's scale
Why Not GitHub Flow?
GitHub Flow is a simpler model: just main and feature branches, deploy from main.
Very close to our choice:
Pros:
- Simple - only
main+ feature branches - Fast - deploy anytime
- Works well with pull requests
Differences from our approach:
- GitHub Flow deploys directly from
main - We tag releases on
maininstead - We add hotfix branches for production patches
Conclusion: We essentially use GitHub Flow + semantic versioning + hotfix branches
Why Annotated Tags?
Annotated vs lightweight tags:
Annotated tags (chosen):
- Contain metadata (tagger, date, message)
- Can include release notes
- Can be GPG signed
- Treated as full Git objects
- Required:
git tag -a v1.0.0 -m "Release 1.0.0"
Lightweight tags (rejected):
- Just pointers to commits
- No metadata
- Created:
git tag v1.0.0
Decision: Always use annotated tags for releases
- Provides complete release history
- Can include release notes in tag message
- Better for professional releases
Why Feature Branches?
Alternatives:
- Direct commits to main - Fast but risky
- Feature branches - Slight overhead but safer
- Pull request workflow - Most structured
Decision: Use feature branches with flexible merge approach
For solo development:
- Feature branches optional for small changes
- Required for larger features
- Merge directly without pull request
For team development:
- Feature branches required
- Pull request review before merge
- Delete branch after merge
Benefits:
- Isolates work in progress
- Enables experimentation
- Keeps main stable
- Scalable to team workflow
Consequences
Positive
- Simple to understand - One primary branch, clear workflows
- Scalable - Works solo, scales to small teams
- Fast integration - Short-lived branches reduce conflicts
- Clean history - Clear tags for every release
- Semantic versioning alignment - Tag strategy matches SemVer
- Hotfix capability - Can patch production releases
- Low overhead - No complex branch management
- Standard practices - Uses modern Git conventions
- Well-documented - Clear workflows for common scenarios
- Flexible - Can use pull requests or direct merges
Negative
- Discipline required - Main must stay stable (tests must pass)
- Manual version management - Must update version, changelog, tag (for V1)
- Solo optimization - Strategy favors individual over large team
- No develop buffer - Changes go directly to main (requires good testing)
Neutral
- Feature branch discipline - Must keep branches short-lived
- Test coverage important - Main stability depends on testing
- Rebase vs merge - Team must choose and be consistent
Mitigations
For main stability:
- Run tests before merging
- Use pull requests for team development
- Establish branch protection rules when team grows
For version management:
- Document clear release process
- Create release checklist
- Consider automation in V2+ if needed
For long-lived branches:
- Review open branches weekly
- Delete stale branches
- Encourage frequent integration
Implementation
Immediate Actions
- Primary branch: Already renamed to
main - Create documentation:
docs/standards/git-branching-strategy.md - Update all references: Ensure docs use
mainconsistently - Initial tag: Tag current state as
v0.1.0
Branch Protection (Future)
When team grows or project matures, add GitHub branch protection:
Settings → Branches → Add rule for main:
- Require pull request reviews (1 approval)
- Require status checks to pass
- Prevent force push
- Prevent deletion
For solo development: Self-discipline instead of enforced rules
Release Process
Development releases (0.x.y):
- Update
starpunk/__init__.pyversion - Update
CHANGELOG.md - Commit:
git commit -m "Bump version to 0.x.y" - Tag:
git tag -a v0.x.y -m "Development release 0.x.y" - Push:
git push origin main v0.x.y
Stable releases (1.0.0+):
- Update version and changelog
- Commit version bump
- Tag:
git tag -a v1.0.0 -m "Release 1.0.0: First stable release" - Push:
git push origin main v1.0.0
Hotfixes:
- Branch:
git checkout -b hotfix/1.0.1-fix v1.0.0 - Fix bug and update version
- Tag:
git tag -a v1.0.1 -m "Hotfix 1.0.1: Bug fix" - Merge:
git checkout main && git merge hotfix/1.0.1-fix - Push:
git push origin main v1.0.1 - Delete:
git branch -d hotfix/1.0.1-fix
Documentation
Created comprehensive documentation:
- Strategy document:
docs/standards/git-branching-strategy.md- Branch types and naming
- Workflows and examples
- Best practices
- Troubleshooting
- This ADR:
docs/decisions/ADR-009-git-branching-strategy.md- Decision rationale
- Alternatives considered
Alternatives Considered
Alternative 1: Git Flow
Description: Use full Git Flow with main, develop, release, hotfix, feature branches
Pros:
- Well-established pattern
- Clear separation of development and production
- Structured release process
- Good for scheduled releases
Cons:
- Too complex for indie project
- Multiple long-lived branches
- Slower integration
- More overhead
- Designed for different release model
Rejected: Complexity doesn't match project scale
Alternative 2: Trunk-Based Development (Pure)
Description: All commits directly to main, no feature branches
Pros:
- Maximum simplicity
- Fastest integration
- No branch management
Cons:
- Risky - broken commits go to main
- No isolation for work in progress
- Difficult for team collaboration
- No experimentation space
Rejected: Too risky, doesn't scale to team
Alternative 3: GitHub Flow (Pure)
Description: main + feature branches, deploy from main continuously
Pros:
- Simple and well-documented
- Works well with pull requests
- Fast deployment
Cons:
- Designed for continuous deployment
- Doesn't emphasize versioned releases
- No hotfix branch pattern
Partially adopted: We use this + semantic versioning + hotfix branches
Alternative 4: Release Branches Primary
Description: Always use release branches, never tag main directly
Pros:
- Clear release preparation phase
- Can stabilize release while main continues
Cons:
- Adds complexity
- Creates long-lived branches
- Overkill for small project
Rejected: Unnecessary complexity for V1
Alternative 5: Keep Master Branch Name
Description: Continue using master instead of main
Pros:
- Traditional name
- No migration needed
- No functional difference
Cons:
- Outdated convention
- Out of step with industry
- Potentially offensive terminology
- New projects use
main
Rejected: Modern standard is main, no reason not to adopt
References
Git Branching Models
- Trunk-Based Development - Pattern we primarily follow
- GitHub Flow - Simplified flow (close to ours)
- Git Flow - More complex model (not adopted)
- GitLab Flow - Hybrid approach
Branch Naming
- GitHub Renaming - Main branch renaming initiative
- Git Branch Naming - Naming conventions
Versioning Integration
- Semantic Versioning - Version numbering
- Git Tagging - Tag documentation
Internal Documentation
- ADR-008: Versioning Strategy - Semantic versioning decision
- Versioning Strategy - Complete versioning spec
- Git Branching Strategy - Complete branching spec
- Development Setup - Development workflow
ADR: 009
Date: 2025-11-18
Status: Accepted
Decision: Adopt simplified trunk-based development with main branch, feature branches, semantic versioning tags, and hotfix capability
Supersedes: None