Git Workflow Patterns
Commit Message Format
<type>(<scope>): <subject>
<body>
<footer>
Types
| Type | Description |
|---|---|
| feat | New feature implementation |
| fix | Bug fixes |
| docs | Documentation changes only |
| style | Code formatting, missing semicolons, etc. |
| refactor | Code restructuring without behavior changes |
| perf | Performance improvements |
| test | Test additions or corrections |
| chore | Build process, auxiliary tools, dependencies |
Rules
- Subject line: Max 50 characters, imperative mood, no period
- Body: Wrap at 72 characters, explain WHY not WHAT
- Write in English
- Be specific and descriptive
Examples
feat(auth): add OAuth2 integration with Google
Implemented Google OAuth2 authentication flow to allow users
to sign in with their Google accounts. This includes:
- OAuth2 configuration and middleware setup
- User profile synchronization
- Session management with JWT tokens
Closes #123
fix(api): resolve race condition in payment processing
The payment webhook handler was not properly locking the
transaction record, causing duplicate charges when webhooks
arrived simultaneously. Added database-level locking to
ensure atomic transaction updates.
Pre-commit Hook Handling
CRITICAL: NEVER use --no-verify flag
Language-specific Checks
JavaScript/TypeScript:
- Linting:
npm run lint,eslint - Type checking:
npm run typecheck,tsc - Formatting:
prettier --check,npm run format - Tests:
npm test,jest,vitest
Python:
- Linting:
ruff check,flake8,pylint - Type checking:
mypy,pyright - Formatting:
black --check,ruff format - Tests:
pytest,python -m unittest
Ruby:
- Linting:
rubocop - Tests:
rspec,rake test
Go:
- Formatting:
go fmt,gofmt - Linting:
golangci-lint run - Tests:
go test
General:
- See
makefile-firstskill for command execution policy - Check package.json scripts section
- Review project documentation
Fixing Pre-commit Failures
- Analyze the error message
- Fix automatically if possible (formatting, linting)
- For type errors: Modify code to fix
- For test failures: Debug and fix
- Stage fixed files and retry commit
Rebase Strategy
When to Rebase
Use git pull --rebase to maintain linear history:
- Before pushing local commits
- When local branch is behind remote
How Rebase Works
- Fetches remote changes
- Temporarily removes your local commits
- Applies remote commits to your branch
- Re-applies your local commits on top
- Creates linear history without merge commits
Conflict Resolution
When conflicts occur:
git statusto identify conflicted files- Resolve each conflict (ours/theirs/manual)
- Remove conflict markers (
<<<<<<<,=======,>>>>>>>) git addresolved filesgit rebase --continue- Or
git rebase --abortto give up
Safety Checks
Before git operations:
- Uncommitted changes: Stash or commit before proceeding
- Remote tracking: Ensure branch tracks a remote
- Network connectivity: Verify connection to remote
- Branch protection: Check if branch has push restrictions
Error Handling Patterns
No remote tracking:
bash1git branch --set-upstream-to=origin/branch-name
Uncommitted changes:
bash1# Option 1: Stash changes 2git stash push -m "Temporary stash for rebase" 3# ... perform rebase ... 4git stash pop 5 6# Option 2: Commit changes first
Network issues:
- Retry with clear error messages
- Check remote URL with
git remote -v - Verify credentials if authentication fails
Pull Request Workflow
- Analyze full commit history (not just latest commit)
- Use
git diff [base-branch]...HEADto see all changes - Draft comprehensive PR summary
- Include test plan with TODOs
- Push with
-uflag if new branch
Git Fixup Pattern
During TDD, each User Story produces a clean commit history through fixup commits:
-
After GREEN phase: Create a semantic commit
bash1git add -A && git commit -m "feat(scope): description" -
After REFACTOR phase: Create a fixup commit targeting the GREEN commit
bash1git add -A && git commit --fixup HEAD -
After review fixes: Create a fixup commit targeting the relevant US commit
bash1git add -A && git commit --fixup <target-sha> -
Before push: Autosquash all fixup commits
bash1GIT_SEQUENCE_EDITOR=true git rebase --autosquash origin/<base-branch>
The result is one clean commit per US in the final history.
Interleaved Commits
Git fixup! commits match their target by commit message, not by position in the log. This means interleaved normal and fixup commits from multiple USs are correctly handled by autosquash.
Before autosquash:
feat(auth): add login flow <- US-1 GREEN
fixup! feat(auth): add login flow <- US-1 REFACTOR
fixup! feat(auth): add login flow <- US-1 review fix
feat(auth): add password reset <- US-2 GREEN
fixup! feat(auth): add password reset <- US-2 REFACTOR
After git rebase --autosquash:
feat(auth): add login flow <- US-1 (REFACTOR + fix absorbed)
feat(auth): add password reset <- US-2 (REFACTOR absorbed)
Each fixup is absorbed into the commit whose message it matches, regardless of intervening commits.
Related Commands
/commit- Commit with semantic message (manual use)/push-to-remote- Autosquash fixups, rebase, and push workflow