Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Git workflow patterns including branching strategies, commit conventions, merge vs rebase, conflict resolution, and collaborative development best practices for teams of all sizes.
.claude/skills/git-workflow/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-07 | ✓→✓ | = Same ✓ | — | — |
| case-21 | ✗→✗ | = Same ✗ | — | — |
Best practices for Git version control, branching strategies, and collaborative development.
Best for continuous deployment and small-to-medium teams.
main (protected, always deployable)
│
├── feature/user-auth → PR → merge to main
├── feature/payment-flow → PR → merge to main
└── fix/login-bug → PR → merge to mainRules:
main is always deployablemainmainBest for teams with strong CI/CD and feature flags.
main (trunk)
│
├── short-lived feature (1-2 days max)
├── short-lived feature
└── short-lived featureRules:
main or very short-lived branchesBest for scheduled releases and enterprise projects.
main (production releases)
│
└── develop (integration branch)
│
├── feature/user-auth
├── feature/payment
│
├── release/1.0.0 → merge to main and develop
│
└── hotfix/critical → merge to main and developRules:
main contains production-ready code onlydevelop is the integration branchdevelop, merge back to developdevelop, merge to main and developmain, merge to both main and develop| Strategy | Team Size | Release Cadence | Best For | |----------|-----------|-----------------|----------| | GitHub Flow | Any | Continuous | SaaS, web apps, startups | | Trunk-Based | 5+ experienced | Multiple/day | High-velocity teams, feature flags | | GitFlow | 10+ | Scheduled | Enterprise, regulated industries |
<type>(<scope>): <subject>
[optional body]
[optional footer(s)]| Type | Use For | Example | |------|---------|---------| | feat | New feature | feat(auth): add OAuth2 login | | fix | Bug fix | fix(api): handle null response in user endpoint | | docs | Documentation | docs(readme): update installation instructions | | style | Formatting, no code change | style: fix indentation in login component | | refactor | Code refactoring | refactor(db): extract connection pool to module | | test | Adding/updating tests | test(auth): add unit tests for token validation | | chore | Maintenance tasks | chore(deps): update dependencies | | perf | Performance improvement | perf(query): add index to users table | | ci | CI/CD changes | ci: add PostgreSQL service to test workflow | | revert | Revert previous commit | revert: revert "feat(auth): add OAuth2 login" |
# BAD: Vague, no context
git commit -m "fixed stuff"
git commit -m "updates"
git commit -m "WIP"
# GOOD: Clear, specific, explains why
git commit -m "fix(api): retry requests on 503 Service Unavailable
The external API occasionally returns 503 errors during peak hours.
Added exponential backoff retry logic with max 3 attempts.
Closes #123"Create .gitmessage in repo root:
# <type>(<scope>): <subject>
# # Types: feat, fix, docs, style, refactor, test, chore, perf, ci, revert
# Scope: api, ui, db, auth, etc.
# Subject: imperative mood, no period, max 50 chars
#
# [optional body] - explain why, not what
# [optional footer] - Breaking changes, closes #issueEnable with: git config commit.template .gitmessage
bash# Creates a merge commit git checkout main git merge feature/user-auth # Result: # * merge commit # |\ # | * feature commits # |/ # * main commits
Use when:
mainbash# Rewrites feature commits onto target branch git checkout feature/user-auth git rebase main # Result: # * feature commits (rewritten) # * main commits
Use when:
mainbash# Update feature branch with latest main (before PR) git checkout feature/user-auth git fetch origin git rebase origin/main # Fix any conflicts # Tests should still pass # Force push (only if you're the only contributor) git push --force-with-lease origin feature/user-auth
# NEVER rebase branches that:
- Have been pushed to a shared repository
- Other people have based work on
- Are protected branches (main, develop)
- Are already merged
# Why: Rebase rewrites history, breaking others' work<type>(<scope>): <description>
Examples:
feat(auth): add SSO support for enterprise users
fix(api): resolve race condition in order processing
docs(api): add OpenAPI specification for v2 endpointsmarkdown## What Brief description of what this PR does. ## Why Explain the motivation and context. ## How Key implementation details worth highlighting. ## Testing - [ ] Unit tests added/updated - [ ] Integration tests added/updated - [ ] Manual testing performed ## Screenshots (if applicable) Before/after screenshots for UI changes. ## Checklist - [ ] Code follows project style guidelines - [ ] Self-review completed - [ ] Comments added for complex logic - [ ] Documentation updated - [ ] No new warnings introduced - [ ] Tests pass locally - [ ] Related issues linked Closes #123
For Reviewers:
For Authors:
bash# Check for conflicts before merge git checkout main git merge feature/user-auth --no-commit --no-ff # If conflicts, Git will show: # CONFLICT (content): Merge conflict in src/auth/login.ts # Automatic merge failed; fix conflicts and then commit the result.
bash# See conflicted files git status # View conflict markers in file # <<<<<<< HEAD # content from main # ======= # content from feature branch # >>>>>>> feature/user-auth # Option 1: Manual resolution # Edit file, remove markers, keep correct content # Option 2: Use merge tool git mergetool # Option 3: Accept one side git checkout --ours src/auth/login.ts # Keep main version git checkout --theirs src/auth/login.ts # Keep feature version # After resolving, stage and commit git add src/auth/login.ts git commit
bash# 1. Keep feature branches small and short-lived # 2. Rebase frequently onto main git checkout feature/user-auth git fetch origin git rebase origin/main # 3. Communicate with team about touching shared files # 4. Use feature flags instead of long-lived branches # 5. Review and merge PRs promptly
# Feature branches
feature/user-authentication
feature/JIRA-123-payment-integration
# Bug fixes
fix/login-redirect-loop
fix/456-null-pointer-exception
# Hotfixes (production issues)
hotfix/critical-security-patch
hotfix/database-connection-leak
# Releases
release/1.2.0
release/2024-01-hotfix
# Experiments/POCs
experiment/new-caching-strategy
poc/graphql-migrationbash# Delete local branches that are merged git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d # Delete remote-tracking references for deleted remote branches git fetch -p # Delete local branch git branch -d feature/user-auth # Safe delete (only if merged) git branch -D feature/user-auth # Force delete # Delete remote branch git push origin --delete feature/user-auth
bash# Save work in progress git stash push -m "WIP: user authentication" # List stashes git stash list # Apply most recent stash git stash pop # Apply specific stash git stash apply stash@{2} # Drop stash git stash drop stash@{0}
MAJOR.MINOR.PATCH
MAJOR: Breaking changes
MINOR: New features, backward compatible
PATCH: Bug fixes, backward compatible
Examples:
1.0.0 → 1.0.1 (patch: bug fix)
1.0.1 → 1.1.0 (minor: new feature)
1.1.0 → 2.0.0 (major: breaking change)bash# Create annotated tag git tag -a v1.2.0 -m "Release v1.2.0 Features: - Add user authentication - Implement password reset Fixes: - Resolve login redirect issue Breaking Changes: - None" # Push tag to remote git push origin v1.2.0 # List tags git tag -l # Delete tag git tag -d v1.2.0 git push origin --delete v1.2.0
bash# Generate changelog from commits git log v1.1.0..v1.2.0 --oneline --no-merges # Or use conventional-changelog npx conventional-changelog -i CHANGELOG.md -s
bash# User identity git config --global user.name "Your Name" git config --global user.email "your@email.com" # Default branch name git config --global init.defaultBranch main # Pull behavior (rebase instead of merge) git config --global pull.rebase true # Push behavior (push current branch only) git config --global push.default current # Auto-correct typos git config --global help.autocorrect 1 # Better diff algorithm git config --global diff.algorithm histogram # Color output git config --global color.ui auto
bash# Add to ~/.gitconfig [alias] co = checkout br = branch ci = commit st = status unstage = reset HEAD -- last = log -1 HEAD visual = log --oneline --graph --all amend = commit --amend --no-edit wip = commit -m "WIP" undo = reset --soft HEAD~1 contributors = shortlog -sn
gitignore# Dependencies node_modules/ vendor/ # Build outputs dist/ build/ *.o *.exe # Environment files .env .env.local .env.*.local # IDE .idea/ .vscode/ *.swp *.swo # OS files .DS_Store Thumbs.db # Logs *.log logs/ # Test coverage coverage/ # Cache .cache/ *.tsbuildinfo
bash# 1. Update main branch git checkout main git pull origin main # 2. Create feature branch git checkout -b feature/user-auth # 3. Make changes and commit git add . git commit -m "feat(auth): implement OAuth2 login" # 4. Push to remote git push -u origin feature/user-auth # 5. Create Pull Request on GitHub/GitLab
bash# 1. Make additional changes git add . git commit -m "feat(auth): add error handling" # 2. Push updates git push origin feature/user-auth
bash# 1. Add upstream remote (once) git remote add upstream https://github.com/original/repo.git # 2. Fetch upstream git fetch upstream # 3. Merge upstream/main into your main git checkout main git merge upstream/main # 4. Push to your fork git push origin main
bash# Undo last commit (keep changes) git reset --soft HEAD~1 # Undo last commit (discard changes) git reset --hard HEAD~1 # Undo last commit pushed to remote git revert HEAD git push origin main # Undo specific file changes git checkout HEAD -- path/to/file # Fix last commit message git commit --amend -m "New message" # Add forgotten file to last commit git add forgotten-file git commit --amend --no-edit
bash#!/bin/bash # .git/hooks/pre-commit # Run linting npm run lint || exit 1 # Run tests npm test || exit 1 # Check for secrets if git diff --cached | grep -E '(password|api_key|secret)'; then echo "Possible secret detected. Commit aborted." exit 1 fi
bash#!/bin/bash # .git/hooks/pre-push # Run full test suite npm run test:all || exit 1 # Check for console.log statements if git diff origin/main | grep -E 'console\.log'; then echo "Remove console.log statements before pushing." exit 1 fi
# BAD: Committing directly to main
git checkout main
git commit -m "fix bug"
# GOOD: Use feature branches and PRs
# BAD: Committing secrets
git add .env # Contains API keys
# GOOD: Add to .gitignore, use environment variables
# BAD: Giant PRs (1000+ lines)
# GOOD: Break into smaller, focused PRs
# BAD: "Update" commit messages
git commit -m "update"
git commit -m "fix"
# GOOD: Descriptive messages
git commit -m "fix(auth): resolve redirect loop after login"
# BAD: Rewriting public history
git push --force origin main
# GOOD: Use revert for public branches
git revert HEAD
# BAD: Long-lived feature branches (weeks/months)
# GOOD: Keep branches short (days), rebase frequently
# BAD: Committing generated files
git add dist/
git add node_modules/
# GOOD: Add to .gitignore| Task | Command | |------|---------| | Create branch | git checkout -b feature/name | | Switch branch | git checkout branch-name | | Delete branch | git branch -d branch-name | | Merge branch | git merge branch-name | | Rebase branch | git rebase main | | View history | git log --oneline --graph | | View changes | git diff | | Stage changes | git add . or git add -p | | Commit | git commit -m "message" | | Push | git push origin branch-name | | Pull | git pull origin branch-name | | Stash | git stash push -m "message" | | Undo last commit | git reset --soft HEAD~1 | | Revert commit | git revert HEAD |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.