# 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/` or `` **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**: ```bash # 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/` or `bugfix/` **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/-` **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**: ```bash # 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/` **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**: ```bash # 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**: `/` **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 ```bash # 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)**: ```bash # 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+)**: ```bash # 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 ```bash # 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): ```bash 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): ```bash git tag v1.0.0 # Don't do this for releases ``` ### Tag Messages **Format**: ``` Release MAJOR.MINOR.PATCH: [Optional longer description] [Release highlights] ``` **Examples**: ```bash 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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**: ``` : (50 chars or less) ``` **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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 - [Versioning Strategy](/home/phil/Projects/starpunk/docs/standards/versioning-strategy.md) - Version numbering scheme - [ADR-008: Versioning Strategy](/home/phil/Projects/starpunk/docs/decisions/ADR-008-versioning-strategy.md) - Versioning decision rationale - [ADR-009: Git Branching Strategy](/home/phil/Projects/starpunk/docs/decisions/ADR-009-git-branching-strategy.md) - This strategy's decision record - [Development Setup](/home/phil/Projects/starpunk/docs/standards/development-setup.md) - Development environment ### External Resources - [Git Branching Model](https://nvie.com/posts/a-successful-git-branching-model/) - Git Flow (inspiration, not followed exactly) - [GitHub Flow](https://guides.github.com/introduction/flow/) - Simpler flow (closer to our approach) - [Semantic Versioning](https://semver.org/) - Version numbering - [Git Documentation](https://git-scm.com/doc) - Official Git documentation --- **Document**: Git Branching Strategy **Version**: 1.0 **Last Updated**: 2025-11-18 **Status**: Active