18 KiB

Git Workflow

Git branching strategy, commit conventions, and version control best practices for Changemaker Lite V2.

Overview

Changemaker Lite V2 uses Git for version control with a structured branching strategy and conventional commit messages.

Key Principles:

  • Main branch always deployable
  • Feature branches for new work
  • Descriptive commit messages
  • Code review via pull requests
  • No direct commits to main

Branch Structure

Main Branches

main - Production branch

  • Always deployable
  • Protected (no direct pushes)
  • Merges only via pull request
  • Tagged with version numbers

v2 - Development branch

  • Active development happens here
  • Features merge into v2 first
  • Tested before merging to main
  • Currently the primary development branch

Feature Branches

Naming: feature/<descriptive-name>

# Create feature branch from v2
git checkout v2
git pull origin v2
git checkout -b feature/add-user-avatar

# Make changes
# ...

# Push to remote
git push -u origin feature/add-user-avatar

Examples:

  • feature/add-user-avatar
  • feature/email-queue-monitoring
  • feature/map-clustering
  • feature/campaign-analytics

Bugfix Branches

Naming: fix/<descriptive-name>

# Create bugfix branch
git checkout v2
git pull origin v2
git checkout -b fix/login-redirect-loop

# Fix bug
# ...

# Push to remote
git push -u origin fix/login-redirect-loop

Examples:

  • fix/login-redirect-loop
  • fix/map-marker-position
  • fix/email-template-rendering

Hotfix Branches

Naming: hotfix/<descriptive-name>

For urgent production fixes:

# Create from main (production)
git checkout main
git pull origin main
git checkout -b hotfix/security-patch

# Fix issue
# ...

# Merge to main AND v2
git checkout main
git merge hotfix/security-patch
git push origin main

git checkout v2
git merge hotfix/security-patch
git push origin v2

Examples:

  • hotfix/security-patch
  • hotfix/critical-database-error

Release Branches

Naming: release/vX.Y.Z

For preparing releases:

# Create release branch from v2
git checkout v2
git pull origin v2
git checkout -b release/v2.1.0

# Prepare release (update version, changelog)
# Test thoroughly
# ...

# Merge to main (after approval)
git checkout main
git merge release/v2.1.0
git tag v2.1.0
git push origin main --tags

# Merge back to v2
git checkout v2
git merge release/v2.1.0
git push origin v2

Feature Development Workflow

Step 1: Create Branch

# Update v2 branch
git checkout v2
git pull origin v2

# Create feature branch
git checkout -b feature/add-user-avatar

# Verify branch
git branch --show-current
# Output: feature/add-user-avatar

Step 2: Make Changes

Edit files, test locally:

# Make changes
vi api/src/modules/users/users.service.ts
vi admin/src/pages/UsersPage.tsx

# Test locally
npm run dev

# Type-check
npm run type-check

# Lint
npm run lint:fix

Step 3: Stage and Commit

# Check status
git status

# Stage specific files (NOT git add .)
git add api/src/modules/users/users.service.ts
git add admin/src/pages/UsersPage.tsx

# Commit with conventional message
git commit -m "feat(users): add avatar upload functionality

Implements avatar upload with image validation and S3 storage.
Adds avatar field to User model and updates UI.

Closes #123"

Step 4: Push to Remote

# Push branch (first time)
git push -u origin feature/add-user-avatar

# Push subsequent commits
git push

Step 5: Create Pull Request

On GitHub/GitLab:

  1. Navigate to repository
  2. Click "New Pull Request"
  3. Select base: v2, compare: feature/add-user-avatar
  4. Fill in PR template (title, description, testing steps)
  5. Request reviewers
  6. Link related issues

Step 6: Address Review Feedback

# Make requested changes
vi api/src/modules/users/users.service.ts

# Stage and commit
git add api/src/modules/users/users.service.ts
git commit -m "fix(users): address review feedback

- Add error handling for upload failures
- Improve validation messages
- Add JSDoc comments"

# Push changes
git push

Step 7: Merge (After Approval)

Squash and Merge (recommended):

  • Combines all commits into one
  • Clean history on v2 branch
  • Preserves individual commits in branch

Merge Commit:

  • Preserves all commits
  • More detailed history
  • Use for large features

Rebase and Merge:

  • Linear history
  • No merge commits
  • Use when v2 has diverged

Step 8: Clean Up

# Delete local branch
git checkout v2
git branch -d feature/add-user-avatar

# Delete remote branch (if not auto-deleted)
git push origin --delete feature/add-user-avatar

# Update v2
git pull origin v2

Commit Messages

Conventional Commits Format

<type>(<scope>): <subject>

<body>

<footer>

Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code formatting (no logic change)
  • refactor: Code restructuring (no behavior change)
  • perf: Performance improvement
  • test: Adding tests
  • chore: Maintenance (dependencies, config)
  • ci: CI/CD changes
  • build: Build system changes

Scopes

Use module/area name:

  • auth - Authentication
  • users - User management
  • campaigns - Campaign module
  • map - Map features
  • email - Email system
  • db - Database changes
  • ui - UI components
  • api - API changes

Examples

Simple commit:

git commit -m "feat(auth): add JWT refresh token rotation"

With body:

git commit -m "feat(campaigns): add email queue monitoring

Implements real-time queue stats dashboard with pause/resume controls.
Shows pending, active, completed, and failed jobs.

Closes #45"

Breaking change:

git commit -m "feat(api)!: change user endpoint response format

BREAKING CHANGE: User endpoint now returns paginated response.
Update client code to handle new format.

Migration guide: docs/migration/v2.1.md"

Multiple changes:

git commit -m "feat(map): add location clustering and popup improvements

- Implement marker clustering for better performance
- Add custom popup with location details
- Improve map controls layout

Closes #67, #68"

Hotfix:

git commit -m "fix(auth)!: patch critical security vulnerability

Fixes CVE-2024-12345 in JWT token validation.
All users must update tokens after deploy.

Security advisory: docs/security/2024-02-13.md"

Git Safety Protocol

From CLAUDE.md - Critical Rules:

NEVER Do These (Unless User Explicitly Requests)

# ❌ NEVER without explicit user approval
git push --force
git push --force-with-lease
git reset --hard
git checkout .
git restore .
git clean -f
git clean -fd
git branch -D
git rebase -i

# ❌ NEVER skip hooks
git commit --no-verify
git push --no-verify

# ❌ NEVER force push to main/master
git push --force origin main  # DANGER!

ALWAYS Do These

# ✅ Stage specific files (not git add .)
git add api/src/modules/auth/auth.service.ts
git add admin/src/pages/LoginPage.tsx

# ✅ Create NEW commits (not --amend after hook failure)
# If pre-commit hook fails, commit did NOT happen
# Fix issue, re-stage, create NEW commit (not amend)

# ✅ Verify changes before commit
git diff --staged

# ✅ Pull before push
git pull origin v2
git push origin feature/my-feature

Commit Co-Authoring (Claude Code)

When Claude assists with code, add co-author:

git commit -m "$(cat <<'EOF'
feat(auth): implement refresh token rotation

Adds atomic refresh token rotation to prevent race conditions
during concurrent refresh requests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
EOF
)"

Or use heredoc:

git commit -m "feat(auth): implement refresh token rotation

Adds atomic refresh token rotation to prevent race conditions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>"

Pull Request Process

PR Template

Create .github/pull_request_template.md:

## Description
<!-- Brief description of changes -->

## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update

## Related Issues
<!-- Link to issue(s): Closes #123, Fixes #456 -->

## Changes Made
<!-- Detailed list of changes -->
-
-
-

## Testing Done
<!-- How were these changes tested? -->
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing performed

## Checklist
- [ ] Code follows style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex logic
- [ ] Documentation updated
- [ ] No new warnings generated
- [ ] Tests pass locally
- [ ] Database migrations included (if applicable)

Code Review Checklist

Reviewer checks:

  • Code matches description
  • Logic is correct
  • Error handling present
  • Tests included
  • TypeScript types correct
  • No security issues
  • No performance issues
  • Documentation updated
  • Follows code style guide
  • No debugging code left

Review Process

  1. Author submits PR

    • Fills out template
    • Self-reviews changes
    • Requests reviewers
  2. Reviewers review

    • Read description
    • Review code changes
    • Test locally (if needed)
    • Leave comments/suggestions
  3. Author addresses feedback

    • Makes requested changes
    • Responds to comments
    • Re-requests review
  4. Final approval

    • Reviewers approve
    • CI/CD checks pass
    • Merge to base branch

Merge Strategies

When to use:

  • Feature branches with multiple commits
  • Want clean history on main/v2
  • Individual commits not important

Result:

v2:  A---B---C---D
                  \
feature:           E---F---G  (squashed into D)

How:

# On GitHub: "Squash and Merge" button

# Manual:
git checkout v2
git merge --squash feature/add-avatar
git commit -m "feat(users): add avatar upload functionality"
git push origin v2

Merge Commit

When to use:

  • Want to preserve all commits
  • Large features with meaningful commit history
  • Release branches

Result:

v2:  A---B-------D
          \     /
feature:   E---F

How:

# On GitHub: "Create a merge commit" button

# Manual:
git checkout v2
git merge feature/add-avatar
git push origin v2

Rebase and Merge

When to use:

  • Want linear history
  • Few commits
  • No merge conflicts

Result:

v2:  A---B---E'---F'

How:

# On GitHub: "Rebase and merge" button

# Manual:
git checkout feature/add-avatar
git rebase v2
git checkout v2
git merge feature/add-avatar
git push origin v2

Version Tags

Semantic Versioning

Format: vMAJOR.MINOR.PATCH

  • MAJOR: Breaking changes
  • MINOR: New features (backward compatible)
  • PATCH: Bug fixes (backward compatible)

Examples:

  • v2.0.0 - Major release (V2 launch)
  • v2.1.0 - New features added
  • v2.1.1 - Bug fixes
  • v2.2.0 - More new features

Creating Tags

# Create annotated tag
git tag -a v2.1.0 -m "Release v2.1.0: Email queue monitoring

New Features:
- Email queue dashboard
- Pause/resume controls
- Job statistics

Bug Fixes:
- Fixed map marker positioning
- Fixed login redirect loop

See CHANGELOG.md for full details"

# Push tag to remote
git push origin v2.1.0

# Push all tags
git push origin --tags

Viewing Tags

# List all tags
git tag

# List tags matching pattern
git tag -l "v2.1.*"

# Show tag details
git show v2.1.0

# Checkout specific tag
git checkout v2.1.0

Common Operations

Update Branch with Latest v2

# While on feature branch
git checkout feature/add-avatar
git fetch origin
git rebase origin/v2

# Or merge (if rebase has conflicts)
git merge origin/v2

Resolve Merge Conflicts

# Attempt merge/rebase
git merge v2
# CONFLICT (content): Merge conflict in api/src/modules/auth/auth.service.ts

# View conflicted files
git status

# Edit conflicted file
vi api/src/modules/auth/auth.service.ts

# Look for conflict markers:
# <<<<<<< HEAD
# Your changes
# =======
# Their changes
# >>>>>>> v2

# Resolve conflict, remove markers

# Stage resolved file
git add api/src/modules/auth/auth.service.ts

# Continue merge
git commit
# Or continue rebase
git rebase --continue

Undo Changes

# Unstage file
git restore --staged api/src/modules/auth/auth.service.ts

# Discard local changes (CAREFUL!)
git restore api/src/modules/auth/auth.service.ts

# Undo last commit (keep changes)
git reset --soft HEAD~1

# Undo last commit (discard changes)
git reset --hard HEAD~1  # ⚠️ DESTRUCTIVE!

# Revert commit (creates new commit)
git revert abc123  # Safer than reset

Stash Changes

# Stash uncommitted changes
git stash

# Stash with message
git stash save "WIP: avatar upload"

# List stashes
git stash list

# Apply stash
git stash apply

# Apply specific stash
git stash apply stash@{1}

# Pop stash (apply and delete)
git stash pop

# Delete stash
git stash drop stash@{0}

View History

# View commit history
git log

# One-line format
git log --oneline

# Graph view
git log --oneline --graph --all

# Filter by author
git log --author="John Doe"

# Filter by date
git log --since="2024-01-01" --until="2024-12-31"

# File history
git log --follow api/src/modules/auth/auth.service.ts

# Search commits
git log --grep="JWT"

Compare Changes

# Compare working directory to staging
git diff

# Compare staging to last commit
git diff --staged

# Compare two branches
git diff v2..feature/add-avatar

# Compare specific file
git diff v2 api/src/modules/auth/auth.service.ts

# Compare commits
git diff abc123..def456

Git Hooks

Pre-commit Hook

Install husky:

npm install --save-dev husky lint-staged
npx husky install

Create pre-commit hook:

# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Run lint-staged
npx lint-staged

Configure lint-staged (package.json):

{
  "lint-staged": {
    "*.{ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{json,md}": [
      "prettier --write"
    ]
  }
}

Hook runs automatically:

git commit -m "feat: add feature"
# Runs ESLint, Prettier on staged files
# Fails commit if errors found

Commit-msg Hook

Validate commit message format:

# .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Validate conventional commit format
npx commitlint --edit $1

Install commitlint:

npm install --save-dev @commitlint/cli @commitlint/config-conventional

Configure (.commitlintrc.json):

{
  "extends": ["@commitlint/config-conventional"],
  "rules": {
    "type-enum": [
      2,
      "always",
      ["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "ci", "build"]
    ],
    "scope-enum": [
      2,
      "always",
      ["auth", "users", "campaigns", "map", "email", "db", "ui", "api"]
    ]
  }
}

.gitignore

Project .gitignore:

# Dependencies
node_modules/
*/node_modules/

# Build outputs
dist/
build/
*/dist/
*/build/

# Environment
.env
.env.local
.env.*.local

# Logs
logs/
*.log
npm-debug.log*

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Testing
coverage/
.nyc_output/

# Temporary
tmp/
temp/
*.tmp

# Database
*.sqlite
*.db

# Prisma
api/.prisma/
api/prisma/.env

# Vite
admin/.vite/
admin/tsconfig.tsbuildinfo

# Docker volumes
postgres-data/
redis-data/

Collaboration

Forks

Fork workflow:

  1. Fork repository on GitHub

  2. Clone your fork:

    git clone https://github.com/your-username/changemaker.lite.git
    
  3. Add upstream remote:

    git remote add upstream https://github.com/original/changemaker.lite.git
    
  4. Create feature branch:

    git checkout -b feature/my-feature
    
  5. Make changes, commit, push to your fork:

    git push origin feature/my-feature
    
  6. Create pull request from your fork to upstream

Sync Fork with Upstream

# Fetch upstream changes
git fetch upstream

# Merge upstream v2 into your v2
git checkout v2
git merge upstream/v2

# Push to your fork
git push origin v2

Best Practices

Do's

  • Pull before push
  • Write descriptive commit messages
  • Stage specific files (not git add .)
  • Review changes before commit (git diff --staged)
  • Test locally before pushing
  • Keep commits focused (one logical change)
  • Use branches for all changes
  • Delete merged branches

Don'ts

  • Commit directly to main
  • Force push without approval
  • Commit large binary files
  • Commit secrets (.env, API keys)
  • Use git add . (stage specific files)
  • Amend commits after pushing
  • Rebase public branches
  • Leave debugging code in commits

Summary

You now know:

  • Branch structure (main, v2, feature, fix, hotfix)
  • Feature development workflow
  • Conventional commit message format
  • Git safety protocol (NEVER force push without approval)
  • Pull request process
  • Merge strategies (squash, merge commit, rebase)
  • Version tagging (semantic versioning)
  • Common Git operations
  • Git hooks (pre-commit, commit-msg)
  • Best practices

Quick Reference:

# Create feature branch
git checkout -b feature/my-feature

# Make changes, stage, commit
git add specific-file.ts
git commit -m "feat(scope): description"

# Push and create PR
git push -u origin feature/my-feature

# After merge, clean up
git checkout v2
git pull origin v2
git branch -d feature/my-feature