Skip to content

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
  2. Fills out template
  3. Self-reviews changes
  4. Requests reviewers

  5. Reviewers review

  6. Read description
  7. Review code changes
  8. Test locally (if needed)
  9. Leave comments/suggestions

  10. Author addresses feedback

  11. Makes requested changes
  12. Responds to comments
  13. Re-requests review

  14. Final approval

  15. Reviewers approve
  16. CI/CD checks pass
  17. 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