Git Philosophy: History as Storytelling

The main Git history is the single source of truth - it should be clean, effective, and read like a well-crafted storybook full of interesting snapshots of development logic. Each commit should tell a meaningful part of the story, making it easy for anyone (including future me) to understand the evolution of the codebase.

The Storybook Approach

  • Each commit represents a logical, complete thought or feature increment

  • Commit messages should explain the “why” behind changes, not just the “what”

  • The history should flow naturally from one logical step to the next

  • Reading the git log should reveal the development reasoning and decision-making process

  • Commits capture meaningful moments in development

  • Each commit should be atomic and focused on a single concern

  • Changes should be grouped logically, not chronologically

  • The story should be engaging and informative for reviewers and maintainers

Public vs Private Development

Clean Public Commits:

  • Published history is immutable and clean

  • Every commit in main/published branches passes tests

  • Commit messages follow consistent conventions

  • No “fix typo”, “oops”, or “WIP” commits in public history

  • Each commit stands alone as a meaningful contribution

Messy Private Iterations:

  • Private development can be messy and experimental

  • Save work frequently with descriptive but informal commit messages

  • Don’t worry about perfect commits during active development

  • Use branches liberally for experimentation

  • Focus on progress over perfection in private branches

Interactive Rebase Strategy

Interactive rebase is the bridge between messy development and clean history:

# Before publishing, clean up the history
git rebase -i HEAD~n  # where n is number of commits to review

# Common rebase operations:
# - squash: Combine multiple commits into one
# - fixup: Merge commit into previous one without editing message
# - reword: Change commit message
# - edit: Modify commit content
# - drop: Remove commit entirely

Squashing Strategy:

  • Squash related fixes together: Combine bug fixes with the commits they fix

  • Group feature work: Multiple commits working on the same feature → single logical commit

  • Remove debugging commits: Squash away temporary logging, console.log, debug prints

  • Combine refactoring: Group refactoring commits that work toward the same goal

Best Practices

Commit Message Format:

type(scope): Brief description of the change

Longer explanation of what and why, not how.
Reference any issues, requirements, or context.

- List specific changes if helpful
- Explain any breaking changes
- Reference related commits or issues

Fixes #123
Resolves SCRUM-456

Branch Strategy

main                           # Clean, release-ready history
├── Feature/user-authentication    # New feature development
├── Feature/payment-integration    # Another feature in progress
├── BugFix/login-validation-error  # Bug fix branch
├── BugFix/memory-leak-fix         # Critical bug fix
├── Hotfix/security-patch          # Emergency production fix
└── WIP/auth-experiment           # Messy experimental branch

Branch Naming Convention

Use categorized prefixes to make branch purposes immediately clear:

Feature/ - New Functionality

Feature/user-dashboard
Feature/api-rate-limiting  
Feature/dark-mode-toggle
Feature/export-functionality

BugFix/ - Issue Resolution

BugFix/login-redirect-loop
BugFix/memory-leak-in-parser
BugFix/timezone-calculation-error
BugFix/css-layout-mobile-fix

Other Common Prefixes

Hotfix/       # Critical production fixes
Refactor/     # Code improvement without feature changes
Docs/         # Documentation updates
Test/         # Test improvements or additions
WIP/          # Work-in-progress/experimental branches
Chore/        # Maintenance tasks (dependency updates, etc.)

Traceability Benefits

This naming convention provides instant context:

  • Easy filtering: git branch | grep Feature/ shows all features in progress

  • Clear purpose: Anyone can understand branch intent at a glance

  • Better organization: IDEs and Git tools can group branches by category

  • Release planning: Quickly identify what features/fixes are ready

  • Code review context: Reviewers know what type of change to expect

Development Workflow

  1. Start from clean main: Always branch from latest main

  2. Create categorized branch: Use appropriate prefix (Feature/, BugFix/, etc.)

  3. Develop messily: Make frequent commits during development

  4. Review privately: Use git log --oneline to review your story

  5. Clean with rebase: Interactive rebase to create logical commits

  6. Final review: Ensure each commit is meaningful and complete

  7. Publish/merge: Clean history ready for public consumption

Workflow Examples

# Starting a new feature
git checkout main
git pull origin main
git checkout -b Feature/user-profile-settings

# Working on a bug fix
git checkout main
git pull origin main  
git checkout -b BugFix/payment-form-validation

# Emergency production fix
git checkout main
git checkout -b Hotfix/security-vulnerability-patch

Tools and Commands

# Review your story before cleaning
git log --oneline --graph HEAD~10..HEAD

# Interactive rebase for cleanup
git rebase -i HEAD~5

# Amend last commit (for small fixes)
git commit --amend

# Split a commit that's too large
git rebase -i HEAD~1  # mark as 'edit'
git reset HEAD~1
git add -p  # stage parts
git commit  # repeat as needed
git rebase --continue

# Preview what rebase will do
git rebase -i --dry-run HEAD~5

Branch Management Commands

# List branches by category
git branch | grep Feature/     # All feature branches
git branch | grep BugFix/      # All bug fix branches  
git branch | grep Hotfix/      # All hotfix branches

# Delete completed feature branches
git branch -d Feature/completed-feature
git push origin --delete Feature/completed-feature

# Find branches by pattern
git branch --list "Feature/*"  # List all feature branches
git branch --list "BugFix/*"   # List all bug fix branches

# See branch creation dates (helpful for cleanup)
git for-each-ref --format='%(refname:short) %(committerdate)' refs/heads/ | sort -k2

# Clean up merged branches (be careful!)
git branch --merged main | grep -E "(Feature/|BugFix/)" | xargs -n 1 git branch -d

Why This Matters

For Current Development:

  • Clearer debugging: Easy to identify when issues were introduced

  • Better code reviews: Logical commits make reviews more effective

  • Faster onboarding: New team members can understand code evolution

  • Confident refactoring: Clean history makes it safe to change code

For Future Maintenance:

  • Archaeological debugging: Use git blame and git log to understand decisions

  • Selective rollbacks: Clean commits allow precise rollbacks

  • Feature archaeology: Understand how features were built and why

  • Documentation: Git history becomes living documentation

For Collaboration:

  • Respectful history: Clean commits respect other developers’ time

  • Merge confidence: Clean feature branches merge without conflicts

  • Release notes: Clean commits make release notes generation easy

  • Bisecting: Clean history makes git bisect actually useful

Examples

Before Cleanup (Messy Development):

feat: add user login form
WIP: trying different validation
fix typo in validation
oops forgot to save file
more validation work
fix linting errors
almost working now
WORKING! user login complete

After Rebase (Clean Story):

feat(auth): Add user login form with validation

Implement user authentication form with:
- Email/password input fields
- Client-side validation with error messages
- Form submission handling
- Integration with auth service API

The form validates email format and password strength
before submission and provides clear error feedback.

Resolves USER-123

Conclusion

Clean Git history is an investment in your future self and your team. It transforms your repository from a messy collection of changes into a readable narrative that tells the story of your code’s evolution. Take the time to craft your commits thoughtfully - your future debugging sessions will thank you.