skills/git-manager/SKILL.md
--- name: git-manager description: Git workflow: branch management, commit conventions, PR patterns, conflict resolution. user-invocable: false effort: low allowed-tools: - Read - Bash --- # Git Workflow Patterns Comprehensive git workflow guidance covering branch management, commit conventions, pull request best practices, conflict resolution, and LazyGit integration. Emphasizes clean history, collaboration patterns, and the user's established branch naming conventions. --- ## When This
npx skillsauth add jasonwarrenuk/goblin-mode skills/git-managerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Comprehensive git workflow guidance covering branch management, commit conventions, pull request best practices, conflict resolution, and LazyGit integration. Emphasizes clean history, collaboration patterns, and the user's established branch naming conventions.
Use this skill when:
Core Development:
feat/ - New features (user-facing or API)enhance/ - Improvements to existing features (not bugs)fix/ - Bug fixeshotfix/ - Critical production fixesCode Quality:
refactor/ - Code restructuring (no behaviour change)types/ - Type definitions (interfaces, types, contracts)perf/ - Performance improvementstest/ - Adding/updating testsdebug/ - Debugging/investigation branches (temporary)Documentation & Content:
docs/ - Documentation changescontent/ - Content updates (copy, text, data files)Styling & UI:
styles/ - Visual styling (colors, fonts, spacing)layout/ - Structural positioning (grid, flexbox, responsive)a11y/ - Accessibility improvementsDependencies & Configuration:
deps/ - Dependency updatesbuild/ - Build system, bundler, toolingconfig/ - Configuration files (non-Claude)agents/ - Claude Code configurationchore/ - Maintenance tasks (cleanup, file moves)CI/CD & DevOps:
ci/ - CI/CD pipeline changesdeploy/ - Deployment-specific changesExperimental:
spike/ - Research/proof-of-concept (not intended for merge)experiment/ - Experimental features (may be discarded)wip/ - Work in progress (explicit "not ready" signal)Structure: <prefix>/<short-description>
Rules:
add-feature, not adds-feature or adding-featurefeat/calculate-user-stats not feat/statsfeat/add-user-dashboard
feat/implement-search
enhance/improve-search-speed
enhance/add-sorting-options
fix/correctly-render-button
fix/handle-null-user
hotfix/patch-security-vulnerability
hotfix/restore-payment-flow
refactor/extract-auth-logic
refactor/simplify-validation
types/add-api-response-types
types/define-user-interfaces
perf/optimize-graph-rendering
perf/lazy-load-images
styles/update-button-colors
layout/make-nav-responsive
docs/add-api-examples
test/add-e2e-tests
deps/upgrade-svelte-5
config/update-prettier-rules
agents/add-roadmap-workflow
chore/remove-deprecated-code
spike/investigate-neo4j
feature/new-stuff # Vague, use feat/ not feature/
fix-button # Missing prefix separator
FIX/button-bug # Uppercase (should be lowercase)
feat/adding-dashboard # Not imperative (should be "add")
fix/bug # Not descriptive enough
refactor/fix-login # Wrong prefix (it's a fix, not refactor)
feat/user_dashboard # Underscores (should be hyphens)
For breaking changes, prefix the description with breaking-:
feat/breaking-api-redesign
refactor/breaking-rename-core-types
enhance/breaking-change-auth-flow
Why prefix not suffix:
git branch | grep breaking/)When creating a new branch, ask these questions in order:
feat/fix/ (or hotfix/ if critical)enhance/refactor/types/perf/styles/layout/docs/test/deps/, config/, build/, agents/ci/ or deploy/spike/ or experiment/chore/Styles vs Layout:
Use styles/ for:
Use layout/ for:
Multiple Changes in One Branch: Use the prefix for the PRIMARY purpose.
Examples:
feat/add-user-dashboardfix/handle-null-userenhance/improve-search-speed<type>(<scope>): <subject>
<body>
<footer>
Type: Same as branch prefixes (feat, fix, docs, etc.) Scope: Component/module affected (optional) Subject: Brief description (50 chars max) Body: Detailed explanation (optional, wrap at 72 chars) Footer: Breaking changes, issue references (optional)
Simple commit:
fix(auth): prevent token expiration race condition
With body:
feat(dashboard): add real-time activity feed
Implements WebSocket connection to stream user activities.
Includes reconnection logic and offline handling.
With footer:
fix(api): correct user data validation
BREAKING CHANGE: email field now required in user creation
Closes #123
Fixes #456
Subject line rules:
Good subjects:
fix(login): handle empty password field
feat(search): add fuzzy matching
refactor(db): extract connection pool logic
docs(readme): update installation steps
Bad subjects:
Fixed bug
Updated stuff
Changes to the user service
WIP - still working on this
Body rules:
Good body:
feat(export): add CSV export functionality
Users can now export their data as CSV files. This addresses
frequent requests from enterprise customers who need to import
data into their analytics tools.
The implementation uses streaming to handle large datasets
without memory issues.
One logical change per commit:
Good (atomic):
1. feat(user): add user profile endpoint
2. test(user): add profile endpoint tests
3. docs(api): document profile endpoint
Bad (mixed concerns):
1. feat(user): add profile endpoint, fix login bug, update dependencies
Commit often, push strategically:
# Local development: Commit frequently
git commit -m "feat(auth): add basic login form"
git commit -m "feat(auth): add form validation"
git commit -m "feat(auth): connect to API"
git commit -m "test(auth): add login tests"
# Before pushing: Consider squashing if appropriate
git rebase -i HEAD~4 # Interactive squash if needed
# Push clean history
git push origin feat/add-user-authentication
From main/master:
# Update main first
git checkout main
git pull origin main
# Create and checkout new branch
git checkout -b feat/add-user-dashboard
# Or in one command
git checkout -b feat/add-user-dashboard origin/main
Branch from another branch:
# When feature depends on another feature
git checkout feat/base-feature
git checkout -b feat/add-dependent-feature
Rebase on main (preferred for clean history):
# Update main
git checkout main
git pull origin main
# Rebase feature branch
git checkout feat/add-user-dashboard
git rebase main
# If conflicts, resolve and continue
git add .
git rebase --continue
# Force push (rewrites history)
git push --force-with-lease origin feat/add-user-dashboard
Merge main (preserves branch history):
git checkout feat/add-user-dashboard
git merge main
# Resolve conflicts if any
git add .
git commit
git push origin feat/add-user-dashboard
When to rebase vs merge:
Delete local branch:
# After merge
git branch -d feat/add-user-dashboard
# Force delete (if not merged)
git branch -D experiment/test-failed-approach
Delete remote branch:
git push origin --delete feat/add-user-dashboard
Prune deleted remote branches:
git fetch --prune
Checklist:
Title format:
Examples:
Add User Authentication System
Fix Login Button Crash on Mobile
Refactor Database Connection Logic
Update API Documentation
Description template:
## What
Brief description of what this PR does.
## Why
Why this change is needed.
## How
High-level explanation of approach.
## Testing
How to test these changes.
## Screenshots (if applicable)
Visual changes shown here.
## Checklist
- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] No breaking changes (or documented)
- [ ] Reviewed own code
Ideal PR size: 200-400 lines changed
Too large (>500 lines):
Split large PRs:
Instead of:
- feat/implement-complete-dashboard (1500 lines)
Split into:
- feat/add-dashboard-layout (300 lines)
- feat/add-dashboard-charts (250 lines)
- feat/add-dashboard-filters (200 lines)
- test/add-dashboard-integration (150 lines)
As author:
As reviewer:
When to use: Preserving complete branch history
git checkout main
git merge --no-ff feat/add-user-dashboard
Pros:
Cons:
When to use: Cleaning up messy branch history
git checkout main
git merge --squash feat/add-user-dashboard
git commit -m "feat(dashboard): add user dashboard system"
Pros:
Cons:
When to use: Clean history with atomic commits
git checkout feat/add-user-dashboard
git rebase main
git checkout main
git merge --ff-only feat/add-user-dashboard
Pros:
Cons:
Conflict markers:
<<<<<<< HEAD
// Current branch code
const user = getCurrentUser();
=======
// Incoming branch code
const user = fetchUser();
>>>>>>> feat/add-user-dashboard
Manual resolution:
# See conflicted files
git status
# Edit files to resolve conflicts
# Remove markers, keep correct code
# Stage resolved files
git add conflicted-file.ts
# Continue operation
git rebase --continue
# or
git merge --continue
Choose theirs/ours:
# Keep incoming changes (theirs)
git checkout --theirs conflicted-file.ts
# Keep current changes (ours)
git checkout --ours conflicted-file.ts
# Then continue
git add conflicted-file.ts
git rebase --continue
Strategies:
Starting LazyGit:
# From project root
lazygit
# Or use alias: lg
lg
Status panel:
space - Stage/unstage filea - Stage allc - CommitP - Pushp - PullBranches panel:
space - Checkout branchn - New branchd - Delete branchr - RebaseM - MergeCommits panel:
s - Squash commitr - Reword commite - Edit commitd - Delete commitR - Revert commitFiles panel:
space - Stage changesd - Discard changese - Edit fileo - Open files - Stash changesStaging workflow:
1. Review changes in Files panel
2. Use arrow keys to navigate
3. Press 'space' to stage individual files
4. Or press 'a' to stage all
5. Press 'c' to commit
6. Write commit message
7. Press 'P' to push
Interactive rebase:
1. Go to Commits panel
2. Navigate to commits
3. Press 'e' to edit/reorder
4. Press 's' to squash
5. Press 'r' to reword
6. Push with force-with-lease
Conflict resolution:
1. LazyGit shows conflicts in red
2. Press 'e' to edit file
3. Resolve conflicts in editor
4. Return to LazyGit
5. Stage resolved files
6. Continue rebase/merge
Save work in progress:
# Stash changes
git stash
# Stash with message
git stash save "WIP: redesign dashboard"
# List stashes
git stash list
# Apply latest stash
git stash apply
# Apply and remove stash
git stash pop
# Apply specific stash
git stash apply stash@{2}
# Drop stash
git stash drop stash@{0}
Apply specific commits to another branch:
# Get commit hash
git log
# Apply commit to current branch
git cherry-pick abc123
# Cherry-pick multiple commits
git cherry-pick abc123 def456
# Cherry-pick without committing
git cherry-pick --no-commit abc123
Binary search for problematic commit:
# Start bisect
git bisect start
# Mark current commit as bad
git bisect bad
# Mark known good commit
git bisect good abc123
# Git checks out middle commit
# Test if bug exists
# Mark as good or bad
git bisect good # or git bisect bad
# Repeat until bug commit found
# Reset when done
git bisect reset
View all HEAD movements:
# Show reflog
git reflog
# Recover deleted branch
git checkout -b recovered-branch abc123
# Undo reset
git reset --hard abc123
Proactively flag breaking changes whenever reviewing code, discussing commits, or observing changes - even when the user is handling commits themselves.
| Change | Example | Breaking? |
|--------|---------|-----------|
| Removed export | export function foo() deleted | YES |
| Renamed export | foo() → bar() | YES |
| Changed parameters | foo(a, b) → foo(a, b, c) (required) | YES |
| Changed parameters | foo(a, b) → foo(a, b, c?) (optional) | NO |
| Reordered parameters | foo(a, b) → foo(b, a) | YES |
| Changed return type | returns string → returns number | YES |
| Narrowed return type | returns string \| null → returns string | NO |
| Widened return type | returns string → returns string \| null | YES |
| Change | Breaking? | |--------|-----------| | Removed property from exported interface | YES | | Added required property to exported interface | YES | | Added optional property to exported interface | NO | | Renamed exported type/interface | YES | | Changed property type | YES | | Made optional property required | YES | | Made required property optional | NO |
| Change | Breaking? | |--------|-----------| | Removed column | YES | | Renamed column | YES | | Changed column type | YES | | Added NOT NULL column without default | YES | | Added nullable column | NO | | Removed table | YES | | Changed foreign key constraints | YES | | Modified RLS policies (restrictive) | YES |
| Change | Breaking? | |--------|-----------| | Removed endpoint | YES | | Changed route path | YES | | Changed HTTP method | YES | | Removed request field | YES (if was required) | | Added required request field | YES | | Removed response field | YES | | Changed response field type | YES | | Changed authentication requirements | YES | | Changed error response format | YES |
| Change | Breaking? | |--------|-----------| | New required env variable | YES | | Removed env variable | YES | | Changed env variable name | YES | | Changed config file format | YES | | Changed default values | MAYBE (assess impact) |
| Change | Breaking? | |--------|-----------| | Removed prop | YES | | Renamed prop | YES | | Changed prop type | YES | | Added required prop | YES | | Added optional prop | NO | | Changed event signature | YES |
When reviewing code, watch for these patterns:
// BREAKING: Removed export
- export function calculateTotal(items: Item[]): number { ... }
// BREAKING: Renamed export
- export const UserContext = createContext(...)
+ export const AuthContext = createContext(...)
// BREAKING: Added required parameter
- export function fetchUser(id: string): Promise<User>
+ export function fetchUser(id: string, options: FetchOptions): Promise<User>
// BREAKING: Changed return type
- export function getConfig(): Config
+ export function getConfig(): Config | null
// BREAKING: Removed interface property
export interface User {
id: string;
name: string;
- email: string;
}
// BREAKING: Added required property
export interface CreateUserRequest {
name: string;
+ email: string; // required, no ?
}
When you detect a potential breaking change, flag it clearly:
⚠️ **Breaking Change Detected**
This change removes the `email` property from the exported `User` interface.
Any code depending on `User.email` will break.
Consider:
- Adding `BREAKING CHANGE: removed email from User interface` to commit footer
- Or using `feat!:` or `refactor!:` prefix
- Branch naming: `feat/breaking-remove-user-email`
When flagging, suggest non-breaking alternatives where possible:
| Breaking Change | Non-Breaking Alternative | |-----------------|-------------------------| | Remove function | Deprecate first, remove in next major | | Rename export | Export both names, deprecate old | | Add required param | Make param optional with default | | Remove field | Mark as deprecated, return null | | Change type | Use union type for transition period |
For breaking changes, use one of:
# Option 1: Footer
feat(api): redesign user authentication
BREAKING CHANGE: removed password field from login endpoint,
now uses OAuth tokens exclusively
# Option 2: ! indicator
feat!: redesign user authentication
# Option 3: Both (for emphasis)
feat(api)!: redesign user authentication
BREAKING CHANGE: removed password field from login endpoint
Git workflow is successful when:
development
Writing style guide for Jason Warren. Use this skill whenever writing prose, reports, documentation, or any substantive text for Jason — including drafting sections, editing existing content, or rewriting passages. Also use when Jason asks you to review or improve writing. Trigger on any request involving writing, drafting, editing, or composing text that isn't purely code. This includes github Pull Requests & Linear tasks
testing
{{ 𝚫𝚫𝚫 }} Check all version number props and update them
tools
{{ 𝛀𝛀𝛀 }} Map out project status, direction, and next steps
development
{{ 𝛀𝛀𝛀 }} Review code changes on the current branch against its open PR