| name | git-workflow |
| description | Git workflow patterns including branching strategies, commit conventions, merge vs rebase, conflict resolution, and collaborative development best practices for teams of all sizes. |
| metadata | {"origin":"ECC"} |
Git Workflow Patterns
Best practices for Git version control, branching strategies, and collaborative development.
When to Activate
- Setting up Git workflow for a new project
- Deciding on branching strategy (GitFlow, trunk-based, GitHub flow)
- Writing commit messages and PR descriptions
- Folding local fix/refactor/review improvements into related unpublished commits
- Resolving merge conflicts
- Managing releases and version tags
- Onboarding new team members to Git practices
Branching Strategies
GitHub Flow (Simple, Recommended for Most)
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 main
Rules:
main is always deployable
- Create feature branches from
main
- Open Pull Request when ready for review
- After approval and CI passes, merge to
main
- Deploy immediately after merge
Trunk-Based Development (High-Velocity Teams)
Best for teams with strong CI/CD and feature flags.
main (trunk)
│
├── short-lived feature (1-2 days max)
├── short-lived feature
└── short-lived feature
Rules:
- Everyone commits to
main or very short-lived branches
- Feature flags hide incomplete work
- CI must pass before merge
- Deploy multiple times per day
GitFlow (Complex, Release-Cycle Driven)
Best 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 develop
Rules:
main contains production-ready code only
develop is the integration branch
- Feature branches from
develop, merge back to develop
- Release branches from
develop, merge to main and develop
- Hotfix branches from
main, merge to both main and develop
When to Use Which
| 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 |
Commit Messages
Conventional Commits Format
<type>(<scope>): <subject>
[optional body]
[optional footer(s)]
Types
| 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" |
Good vs Bad Examples
# 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"
Commit Message Template
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 #issue
Enable with: git config commit.template .gitmessage
Merge vs Rebase
Merge (Preserves History)
git checkout main
git merge feature/user-auth
Use when:
- Merging feature branches into
main
- You want to preserve exact history
- Multiple people worked on the branch
- The branch has been pushed and others may have based work on it
Rebase (Linear History)
git checkout feature/user-auth
git rebase main
Use when:
- Updating your local feature branch with latest
main
- You want a linear, clean history
- The branch is local-only (not pushed)
- You're the only one working on the branch
Rebase Workflow
git checkout feature/user-auth
git fetch origin
git rebase origin/main
git push --force-with-lease origin feature/user-auth
When NOT to Rebase
# 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
Pull Request Workflow
Local Fixup Commits
When a fix, refactor, or review improvement belongs to an existing commit, prefer a fixup
commit over a new standalone commit only when the target commit is local and unpublished.
- Inspect the branch and target commit:
git fetch --prune
git status --short
git log --oneline --decorate -20
git log --oneline @{upstream}..HEAD
git branch -r --contains <sha>
- Use
git commit --fixup <sha> only when:
- the staged changes belong entirely to that commit's original intent;
<sha> is a non-merge commit on the current branch;
<sha> is ahead of the upstream tracking branch; and
- no remote branch contains
<sha>.
- Stage only the files or hunks for that fixup. Never mix unrelated changes into one fixup.
- Use a normal semantic commit when no single target commit owns the change, the change adds
a distinct capability, the target is published, or publication status cannot be proven.
Before the first push or PR creation, fold local fixups into their targets:
GIT_SEQUENCE_EDITOR=: git rebase -i --autosquash <base>
Choose <base> as the merge base with the target branch or the parent of the oldest local
target commit. Obtain explicit confirmation before this history rewrite, then verify the
rewritten history and run relevant checks again before pushing.
Never rewrite a published branch by default. If a fixup target or branch is already remote,
create a normal follow-up commit. Rebase and git push --force-with-lease require explicit user
authorization and must never use plain --force.
PR Title Format
<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 endpoints
PR Description Template
## 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
Code Review Checklist
For Reviewers:
For Authors:
Conflict Resolution
Identify Conflicts
git checkout main
git merge feature/user-auth --no-commit --no-ff
Resolve Conflicts
git status
git mergetool
git checkout --ours src/auth/login.ts
git checkout --theirs src/auth/login.ts
git add src/auth/login.ts
git commit
Conflict Prevention Strategies
git checkout feature/user-auth
git fetch origin
git rebase origin/main
Branch Management
Naming Conventions
# 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-migration
Branch Cleanup
git branch --merged main | grep -v "^\*\|main" | xargs -n 1 git branch -d
git fetch -p
git branch -d feature/user-auth
git branch -D feature/user-auth
git push origin --delete feature/user-auth
Stash Workflow
git stash push -m "WIP: user authentication"
git stash list
git stash pop
git stash apply stash@{2}
git stash drop stash@{0}
Release Management
Semantic Versioning
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)
Creating Releases
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"
git push origin v1.2.0
git tag -l
git tag -d v1.2.0
git push origin --delete v1.2.0
Changelog Generation
git log v1.1.0..v1.2.0 --oneline --no-merges
npx conventional-changelog -i CHANGELOG.md -s
Git Configuration
Essential Configs
git config --global user.name "Your Name"
git config --global user.email "your@email.com"
git config --global init.defaultBranch main
git config --global pull.rebase true
git config --global push.default current
git config --global help.autocorrect 1
git config --global diff.algorithm histogram
git config --global color.ui auto
Useful Aliases
[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 Patterns
# 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
Common Workflows
Starting a New Feature
git checkout main
git pull origin main
git checkout -b feature/user-auth
git add .
git commit -m "feat(auth): implement OAuth2 login"
git push -u origin feature/user-auth
Updating a PR with New Changes
git add .
git commit -m "feat(auth): add error handling"
git push origin feature/user-auth
Syncing Fork with Upstream
git remote add upstream https://github.com/original/repo.git
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
Undoing Mistakes
git reset --soft HEAD~1
git reset --hard HEAD~1
git revert HEAD
git push origin main
git checkout HEAD -- path/to/file
git commit --amend -m "New message"
git add forgotten-file
git commit --amend --no-edit
Git Hooks
Pre-Commit Hook
#!/bin/bash
npm run lint || exit 1
npm test || exit 1
if git diff --cached | grep -E '(password|api_key|secret)'; then
echo "Possible secret detected. Commit aborted."
exit 1
fi
Pre-Push Hook
#!/bin/bash
npm run test:all || exit 1
if git diff origin/main | grep -E 'console\.log'; then
echo "Remove console.log statements before pushing."
exit 1
fi
Anti-Patterns
# 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
Quick Reference
| 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 |