# 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**:
```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/<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**:
```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/<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**:
```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**: `<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

```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: <Brief description>

[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**:
```
<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

```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
