Files
StarPunk/docs/standards/git-branching-strategy.md
2025-11-18 19:21:31 -07:00

16 KiB

Git Branching Strategy

Overview

This document defines the git branching strategy for StarPunk. The strategy balances simplicity with discipline, appropriate for a personal/small-team project while supporting semantic versioning and clean releases.

Philosophy: Keep it simple. Minimize long-lived branches. Integrate frequently.

Primary Branch

Branch: main

Purpose: The primary development branch and source of truth

Characteristics:

  • Always contains the latest development code
  • Should be stable and pass all tests
  • Protected from direct commits (use pull requests)
  • Tagged for releases
  • Never rewritten or force-pushed

Version state: Development version (0.x.y) until first stable release (1.0.0)

Branch Types

Feature Branches

Naming: feature/<description> or <description>

Purpose: Develop new features or enhancements

Lifecycle:

  • Branch from: main
  • Merge into: main
  • Delete after: Merged or abandoned

Examples:

  • feature/micropub-endpoint
  • feature/rss-feed
  • indieauth-integration
  • note-markdown-support

Workflow:

# Create feature branch
git checkout -b feature/micropub-endpoint main

# Work on feature
git add .
git commit -m "Add micropub endpoint skeleton"

# Keep updated with main
git fetch origin
git rebase origin/main

# When ready, create pull request or merge
git checkout main
git merge feature/micropub-endpoint

# Delete feature branch
git branch -d feature/micropub-endpoint

Fix Branches

Naming: fix/<description> or bugfix/<description>

Purpose: Fix bugs in development code

Lifecycle:

  • Branch from: main
  • Merge into: main
  • Delete after: Merged

Examples:

  • fix/slug-generation-unicode
  • bugfix/rss-invalid-xml
  • fix/auth-redirect-loop

Workflow: Same as feature branches

Hotfix Branches

Naming: hotfix/<version>-<description>

Purpose: Critical fixes to production releases (post-1.0.0)

Lifecycle:

  • Branch from: Release tag (e.g., v1.0.0)
  • Merge into: main
  • Tag as new release: v1.0.1
  • Delete after: Released

Examples:

  • hotfix/1.0.1-security-path-traversal
  • hotfix/1.1.1-rss-encoding

Workflow:

# Create hotfix from release tag
git checkout -b hotfix/1.0.1-security-fix v1.0.0

# Fix the issue
git commit -m "Fix security vulnerability"

# Update version
# Edit starpunk/__init__.py: __version__ = "1.0.1"
# Update CHANGELOG.md

git commit -m "Bump version to 1.0.1"

# Tag the hotfix
git tag -a v1.0.1 -m "Hotfix 1.0.1: Security vulnerability fix"

# Merge into main
git checkout main
git merge hotfix/1.0.1-security-fix

# Push
git push origin main v1.0.1

# Delete hotfix branch
git branch -d hotfix/1.0.1-security-fix

Release Branches (Optional)

Naming: release/<version>

Purpose: Prepare for release (testing, docs, version bumps)

Used when: Release preparation requires multiple commits and testing

Note: For V1 (simple project), we likely don't need release branches. We can prepare releases directly on main or feature branches.

If used:

# Create release branch
git checkout -b release/1.0.0 main

# Prepare release
# - Update version numbers
# - Update CHANGELOG.md
# - Update documentation
# - Final testing

git commit -m "Prepare release 1.0.0"

# Tag
git tag -a v1.0.0 -m "Release 1.0.0: First stable release"

# Merge to main
git checkout main
git merge release/1.0.0

# Push
git push origin main v1.0.0

# Delete release branch
git branch -d release/1.0.0

Branch Naming Conventions

Format

Preferred: <type>/<description>

Types:

  • feature/ - New features
  • fix/ - Bug fixes
  • bugfix/ - Bug fixes (alternative)
  • hotfix/ - Production hotfixes
  • docs/ - Documentation only
  • refactor/ - Code refactoring
  • test/ - Test additions/changes
  • chore/ - Maintenance tasks

Description:

  • Use lowercase
  • Use hyphens to separate words
  • Be descriptive but concise
  • Reference issue number if applicable

Examples

Good:

  • feature/micropub-create-action
  • fix/rss-pubdate-timezone
  • docs/api-documentation
  • refactor/note-storage-layer
  • test/slug-generation-edge-cases
  • chore/update-dependencies

Acceptable (simple description):

  • micropub-endpoint
  • rss-feed
  • auth-integration

Avoid:

  • my-feature (too vague)
  • feature/Feature1 (not descriptive)
  • fix_bug (use hyphens)
  • FEATURE-MICROPUB (use lowercase)

Workflows

Development Workflow (Pre-1.0)

For single developer:

  1. Work directly on main for small changes
  2. Use feature branches for larger features
  3. Commit frequently with clear messages
  4. Tag development milestones (e.g., v0.1.0)

For multiple developers:

  1. Always use feature branches
  2. Create pull requests
  3. Review before merging
  4. Delete feature branches after merge

Feature Development

# Start feature
git checkout -b feature/new-feature main

# Develop
git add file.py
git commit -m "Implement core functionality"

# Keep updated
git fetch origin
git rebase origin/main

# Finish
git checkout main
git merge feature/new-feature
git push origin main
git branch -d feature/new-feature

Release Workflow

For development releases (0.x.y):

# Ensure on main
git checkout main

# Update version
# Edit starpunk/__init__.py
# Update CHANGELOG.md

# Commit
git add starpunk/__init__.py CHANGELOG.md
git commit -m "Bump version to 0.2.0"

# Tag
git tag -a v0.2.0 -m "Development release 0.2.0: Phase 1.2 complete"

# Push
git push origin main v0.2.0

For stable releases (1.0.0+):

# Option 1: Direct on main (simple)
git checkout main
# Update version, changelog, documentation
git commit -m "Prepare release 1.0.0"
git tag -a v1.0.0 -m "Release 1.0.0: First stable release"
git push origin main v1.0.0

# Option 2: Using release branch (if needed)
git checkout -b release/1.0.0 main
# Prepare release
git commit -m "Prepare release 1.0.0"
git tag -a v1.0.0 -m "Release 1.0.0: First stable release"
git checkout main
git merge release/1.0.0
git push origin main v1.0.0
git branch -d release/1.0.0

Hotfix Workflow

# Create from release tag
git checkout -b hotfix/1.0.1-critical-fix v1.0.0

# Fix
git commit -m "Fix critical bug"

# Version bump
git commit -m "Bump version to 1.0.1"

# Tag
git tag -a v1.0.1 -m "Hotfix 1.0.1: Critical bug fix"

# Merge to main
git checkout main
git merge hotfix/1.0.1-critical-fix

# Push
git push origin main v1.0.1

# Clean up
git branch -d hotfix/1.0.1-critical-fix

Branch Protection Rules

Main Branch Protection

For solo development:

  • Recommended but not enforced via GitHub
  • Self-discipline: treat main as protected
  • Don't force push
  • Don't rewrite history

For team development:

  • Require pull request reviews
  • Require status checks to pass
  • Prevent force push
  • Prevent deletion

GitHub settings (when ready):

Settings → Branches → Add branch protection rule

Branch name pattern: main

Protect matching branches:
☑ Require a pull request before merging
  ☑ Require approvals (1)
☑ Require status checks to pass before merging
  ☑ Require branches to be up to date before merging
☑ Require conversation resolution before merging
☑ Do not allow bypassing the above settings
☐ Allow force pushes (NEVER enable)
☐ Allow deletions (NEVER enable)

Tagging Strategy

Tag Format

Version tags: vMAJOR.MINOR.PATCH[-PRERELEASE]

Examples:

  • v0.1.0 - Development release
  • v1.0.0 - First stable release
  • v1.0.1 - Patch release
  • v1.1.0 - Minor release
  • v2.0.0 - Major release
  • v1.0.0-alpha.1 - Pre-release

Tag Types

Annotated tags (ALWAYS use for releases):

git tag -a v1.0.0 -m "Release 1.0.0: First stable release"

Why annotated:

  • Contains tagger, date, message
  • Can include release notes
  • Can be GPG signed
  • Treated as full Git objects
  • Better for releases

Lightweight tags (NEVER use for releases):

git tag v1.0.0  # Don't do this for releases

Tag Messages

Format:

Release MAJOR.MINOR.PATCH: <Brief description>

[Optional longer description]
[Release highlights]

Examples:

git tag -a v1.0.0 -m "Release 1.0.0: First stable release

Complete IndieWeb CMS implementation with:
- IndieAuth authentication
- Micropub publishing endpoint
- RSS feed generation
- File-based note storage
- Markdown support"

git tag -a v1.0.1 -m "Hotfix 1.0.1: Security vulnerability fix"

git tag -a v0.2.0 -m "Development release 0.2.0: Phase 1.2 complete"

Viewing Tags

# List all tags
git tag

# List tags with messages
git tag -n

# Show tag details
git show v1.0.0

# List tags matching pattern
git tag -l "v1.0.*"

Pushing Tags

# Push specific tag
git push origin v1.0.0

# Push all tags
git push origin --tags

# Delete remote tag (if needed)
git push origin :refs/tags/v1.0.0

Integration with Semantic Versioning

Version-to-Branch Mapping

Development phase (0.x.y):

  • Work on main
  • Tag development milestones: v0.1.0, v0.2.0, etc.
  • Breaking changes allowed

Stable releases (1.x.y):

  • Work on main or feature branches
  • Tag stable releases: v1.0.0, v1.1.0, etc.
  • Breaking changes require major version bump

Major releases (2.0.0+):

  • Work on main or feature branches
  • Tag major releases: v2.0.0, v3.0.0, etc.
  • Document breaking changes thoroughly

Branch-to-Release Flow

feature/micropub → main → v0.1.0 (development)
feature/rss      → main → v0.2.0 (development)
feature/auth     → main → v0.3.0 (development)
                   main → v1.0.0 (stable)
fix/bug          → main → v1.0.1 (patch)
feature/new      → main → v1.1.0 (minor)
feature/breaking → main → v2.0.0 (major)

Common Scenarios

Scenario 1: Developing a New Feature

# Create feature branch
git checkout -b feature/micropub-endpoint main

# Develop
git commit -am "Add micropub create action"
git commit -am "Add micropub update action"

# Keep updated with main
git fetch origin
git rebase origin/main

# Merge when ready
git checkout main
git merge feature/micropub-endpoint

# Push and clean up
git push origin main
git branch -d feature/micropub-endpoint

Scenario 2: Releasing a Development Version

# Update version
echo '__version__ = "0.2.0"' > starpunk/__init__.py

# Update changelog
# Edit CHANGELOG.md

# Commit
git commit -am "Bump version to 0.2.0"

# Tag
git tag -a v0.2.0 -m "Development release 0.2.0"

# Push
git push origin main v0.2.0

Scenario 3: First Stable Release

# Final preparations on main
git commit -am "Update documentation for 1.0.0"

# Version bump
echo '__version__ = "1.0.0"' > starpunk/__init__.py
# Edit CHANGELOG.md

git commit -am "Bump version to 1.0.0"

# Tag
git tag -a v1.0.0 -m "Release 1.0.0: First stable release"

# Push
git push origin main v1.0.0

Scenario 4: Critical Production Bug

# Create hotfix from last release
git checkout -b hotfix/1.0.1-security-fix v1.0.0

# Fix the bug
git commit -am "Fix security vulnerability"

# Version bump
echo '__version__ = "1.0.1"' > starpunk/__init__.py
# Edit CHANGELOG.md
git commit -am "Bump version to 1.0.1"

# Tag
git tag -a v1.0.1 -m "Hotfix 1.0.1: Security vulnerability fix"

# Merge to main
git checkout main
git merge hotfix/1.0.1-security-fix

# Push
git push origin main v1.0.1

# Clean up
git branch -d hotfix/1.0.1-security-fix

Scenario 5: Multiple Features in Progress

# Developer 1: Feature A
git checkout -b feature/feature-a main
# Work on feature A

# Developer 2: Feature B
git checkout -b feature/feature-b main
# Work on feature B

# Feature A finishes first
git checkout main
git merge feature/feature-a
git push origin main

# Feature B rebases onto updated main
git checkout feature/feature-b
git rebase origin/main
# Continue work

# Feature B finishes
git checkout main
git merge feature/feature-b
git push origin main

Best Practices

Do

  1. Commit often with clear messages
  2. Pull before push to avoid conflicts
  3. Rebase feature branches to keep history clean
  4. Delete merged branches to reduce clutter
  5. Tag releases with annotated tags
  6. Write descriptive commit messages (50 char summary, then details)
  7. Test before merging to main
  8. Use pull requests for team development
  9. Keep main stable - always passing tests
  10. Document breaking changes in commits and changelog

Don't

  1. Never force push to main
  2. Never rewrite history on main
  3. Don't commit directly to main (team development)
  4. Don't merge broken code - tests must pass
  5. Don't create long-lived branches - integrate frequently
  6. Don't use lightweight tags for releases
  7. Don't forget to push tags after creating them
  8. Don't merge without updating from origin first
  9. Don't commit secrets or sensitive data
  10. Don't skip version bumps before tagging

Commit Message Format

Format:

<type>: <summary> (50 chars or less)

<optional detailed description>

<optional footer: references, breaking changes>

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation
  • style: Formatting, whitespace
  • refactor: Code refactoring
  • test: Adding tests
  • chore: Maintenance tasks

Examples:

feat: Add Micropub create endpoint

Implements the create action for Micropub specification.
Supports h-entry posts with content, name, and published properties.

Refs: #15

fix: Correct RSS pubDate timezone handling

Previously used local timezone, now uses UTC as per RSS spec.

Fixes: #23

docs: Update installation instructions

chore: Bump version to 1.0.0

Troubleshooting

Problem: Merge Conflict

# During merge
git merge feature/my-feature
# CONFLICT (content): Merge conflict in file.py

# Resolve conflicts
# Edit file.py, resolve conflicts
git add file.py
git commit -m "Merge feature/my-feature"

Problem: Accidentally Committed to Main

# If not pushed yet
git reset HEAD~1  # Undo last commit, keep changes
git stash         # Save changes
git checkout -b feature/my-feature  # Create feature branch
git stash pop     # Apply changes
git commit -am "Feature implementation"

Problem: Need to Update Feature Branch

# Option 1: Rebase (clean history)
git checkout feature/my-feature
git rebase origin/main

# Option 2: Merge (preserves history)
git checkout feature/my-feature
git merge origin/main

Problem: Wrong Tag Name

# Delete local tag
git tag -d v1.0.0

# Delete remote tag
git push origin :refs/tags/v1.0.0

# Create correct tag
git tag -a v1.0.1 -m "Release 1.0.1"
git push origin v1.0.1

References

Internal Documentation

External Resources


Document: Git Branching Strategy Version: 1.0 Last Updated: 2025-11-18 Status: Active