Git is flexible enough to support almost any workflow. That flexibility is both a blessing and a curse — without clear patterns, teams end up with merge conflicts, lost work, and frustration. Here are workflows that work.

Solo Developer: Simple Trunk

When you’re working alone, keep it simple:

1
2
3
4
5
6
7
8
# Work directly on main
git checkout main
git pull

# Make changes
git add .
git commit -m "Add feature X"
git push

That’s it. No branches, no PRs, no ceremony. Save complexity for when you need it.

When to Add Branches

Even solo, branches help when:

  • Experimenting with risky changes
  • Working on multiple features simultaneously
  • Needing to switch context quickly
1
2
3
4
5
6
# Feature branch
git checkout -b experiment/new-approach
# ... work ...
git checkout main
git merge experiment/new-approach
git branch -d experiment/new-approach

Small Team: GitHub Flow

For teams of 2-10, GitHub Flow is the sweet spot:

  1. main is always deployable
  2. Create feature branches from main
  3. Open PR when ready for review
  4. Merge to main after approval
  5. Deploy from main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Start feature
git checkout main
git pull
git checkout -b feature/user-auth

# Work and commit
git add .
git commit -m "Add login form"
git push -u origin feature/user-auth

# Open PR on GitHub/GitLab
# After review and approval, merge via UI

# Clean up
git checkout main
git pull
git branch -d feature/user-auth

Branch Naming

1
2
3
4
5
6
feature/short-description    # New features
fix/bug-description          # Bug fixes
hotfix/critical-issue        # Urgent production fixes
chore/maintenance-task       # Non-feature work
docs/what-documented         # Documentation
refactor/what-changed        # Code restructuring

Larger Teams: GitFlow

For teams with scheduled releases and multiple environments:

mhrdfaoeeeitlvanfeetialuxsorepe(((i((erndpmeterelevoregedgarluesaocnetptcimiypoeornnnfe)t)ip)x)es)

Branches:

  • main — Production code, tagged releases only
  • develop — Integration branch, always deployable to staging
  • feature/* — New features, branch from develop
  • release/* — Release preparation, branch from develop
  • hotfix/* — Emergency fixes, branch from main
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# Start feature
git checkout develop
git pull
git checkout -b feature/new-thing

# Finish feature
git checkout develop
git merge --no-ff feature/new-thing
git push
git branch -d feature/new-thing

# Start release
git checkout develop
git checkout -b release/1.2.0
# ... version bumps, final fixes ...

# Finish release
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Release 1.2.0"
git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0

# Hotfix
git checkout main
git checkout -b hotfix/security-patch
# ... fix ...
git checkout main
git merge --no-ff hotfix/security-patch
git tag -a v1.2.1 -m "Security patch"
git checkout develop
git merge --no-ff hotfix/security-patch
git branch -d hotfix/security-patch

Trunk-Based Development

For teams with strong CI/CD and feature flags:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Everyone works on main
git checkout main
git pull

# Short-lived branches (< 1 day)
git checkout -b short-feature
# ... small, focused change ...
git checkout main
git merge short-feature
git push
git branch -d short-feature

Key principles:

  • Branches live less than a day
  • Feature flags hide incomplete work
  • Strong CI catches issues immediately
  • Everyone integrates frequently
1
2
3
4
5
# Feature flags instead of long branches
if feature_flags.enabled("new_checkout"):
    return new_checkout_flow()
else:
    return old_checkout_flow()

Commit Messages

Conventional Commits

tLFyoipnxege(essrc#oe1px2ep3)l:ansahtoirotndiefscnreiepdteido.n

Types:

  • feat: — New feature
  • fix: — Bug fix
  • docs: — Documentation
  • style: — Formatting (no code change)
  • refactor: — Code restructuring
  • test: — Adding tests
  • chore: — Maintenance
1
2
3
4
5
6
feat(auth): add OAuth2 login support

Implements Google and GitHub OAuth providers.
Includes token refresh and secure storage.

Closes #456

Good vs Bad

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Bad
git commit -m "fix"
git commit -m "WIP"
git commit -m "stuff"
git commit -m "asdfasdf"

# Good
git commit -m "fix(api): handle null response from payment gateway"
git commit -m "feat(ui): add dark mode toggle to settings"
git commit -m "docs: update API authentication examples"

Handling Common Situations

Sync Feature Branch with Main

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Option 1: Merge (preserves history)
git checkout feature/my-feature
git merge main

# Option 2: Rebase (cleaner history)
git checkout feature/my-feature
git rebase main

# If conflicts, resolve then:
git add .
git rebase --continue

Undo Last Commit

1
2
3
4
5
6
7
8
# Keep changes staged
git reset --soft HEAD~1

# Keep changes unstaged
git reset HEAD~1

# Discard changes completely (careful!)
git reset --hard HEAD~1

Fix Commit Message

1
2
3
4
5
6
# Last commit
git commit --amend -m "New message"

# Older commit (interactive rebase)
git rebase -i HEAD~3
# Change 'pick' to 'reword' for the commit

Squash Commits Before PR

1
2
3
git rebase -i HEAD~5
# Change 'pick' to 'squash' for commits to combine
# Keep first commit as 'pick'

Cherry-Pick Specific Commit

1
2
git checkout main
git cherry-pick abc1234

Stash Work in Progress

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Save current changes
git stash

# Do other work...

# Restore changes
git stash pop

# List stashes
git stash list

# Apply specific stash
git stash apply stash@{2}

Pull Request Best Practices

Before Opening

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Update with latest main
git checkout main
git pull
git checkout feature/my-feature
git rebase main

# Run tests locally
npm test

# Check for lint issues
npm run lint

# Review your own changes
git diff main...feature/my-feature

PR Template

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
## Summary
Brief description of changes.

## Changes
- Added X
- Modified Y
- Removed Z

## Testing
- [ ] Unit tests pass
- [ ] Manual testing completed
- [ ] Edge cases considered

## Screenshots
(if UI changes)

## Related Issues
Closes #123

Review Checklist

  • Code runs and tests pass
  • Logic is correct and handles edge cases
  • Code is readable and well-documented
  • No security vulnerabilities
  • Performance is acceptable
  • Changes match the PR description

Branch Protection

Configure in GitHub/GitLab:

1
2
3
4
5
6
# Required for main branch:
- Require PR reviews (1-2 approvers)
- Require status checks (CI must pass)
- Require up-to-date branches
- No force pushes
- No deletions

Quick Reference

SituationCommand
Start featuregit checkout -b feature/name
Sync with maingit rebase main
Squash commitsgit rebase -i HEAD~n
Undo last commitgit reset --soft HEAD~1
Stash changesgit stash / git stash pop
Cherry-pickgit cherry-pick <sha>
Clean branchesgit branch -d name
Force push (careful!)git push --force-with-lease

The best workflow is one your team actually follows. Start simple (GitHub Flow), add complexity only when needed. Clear conventions and automation matter more than the specific workflow you choose.