1010 lines
18 KiB
Markdown

# 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>`
```bash
# 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>`
```bash
# 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:
```bash
# 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:
```bash
# 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
```bash
# 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:
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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:**
```bash
git commit -m "feat(auth): add JWT refresh token rotation"
```
**With body:**
```bash
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:**
```bash
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:**
```bash
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:**
```bash
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)
```bash
# ❌ 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
```bash
# ✅ 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:
```bash
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:**
```bash
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`:
```markdown
## 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
### Squash and Merge (Recommended)
**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:**
```bash
# 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:**
```bash
# 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:**
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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:
```bash
npm install --save-dev husky lint-staged
npx husky install
```
**Create pre-commit hook:**
```bash
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Run lint-staged
npx lint-staged
```
**Configure lint-staged (package.json):**
```json
{
"lint-staged": {
"*.{ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}
```
**Hook runs automatically:**
```bash
git commit -m "feat: add feature"
# Runs ESLint, Prettier on staged files
# Fails commit if errors found
```
### Commit-msg Hook
Validate commit message format:
```bash
# .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
# Validate conventional commit format
npx commitlint --edit $1
```
**Install commitlint:**
```bash
npm install --save-dev @commitlint/cli @commitlint/config-conventional
```
**Configure (.commitlintrc.json):**
```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:
```bash
git clone https://github.com/your-username/changemaker.lite.git
```
3. Add upstream remote:
```bash
git remote add upstream https://github.com/original/changemaker.lite.git
```
4. Create feature branch:
```bash
git checkout -b feature/my-feature
```
5. Make changes, commit, push to your fork:
```bash
git push origin feature/my-feature
```
6. Create pull request from your fork to upstream
### Sync Fork with Upstream
```bash
# 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
## Related Documentation
- **Setup:** [Local Development Setup](local-setup.md)
- **Code Style:** [Code Style Guide](code-style.md)
- **Testing:** [Testing Guide](testing.md)
- **Contributing:** [Contributing Guide](../contributing.md)
## 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:**
```bash
# 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
```