DEV Community

Alex Chen
Alex Chen

Posted on

Git Workflows: From Solo to Team (2026)

Git Workflows: From Solo to Team (2026)

Git isn't just commit and push. A good workflow prevents disasters before they happen.

The Essentials Everyone Needs

# Before any workflow: configure your identity!
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main    # Not master anymore

# Useful defaults
git config --global core.autocrlf input         # Normalize line endings on checkout
git config --global core.whitespace trailing-space,space-before-tab
git config --global push.autoSetupRemote true   # git push sets upstream automatically
git config --global rebase.autoStash true        # Auto-stash before rebase/pull
Enter fullscreen mode Exit fullscreen mode

Solo Workflow: Simple but Effective

main ──────────────────────────────→ (deployed to production)
  ↑
  │  Your daily work:
  │  1. git pull (sync with remote)
  │  2. Create feature branch
  │  3. Commit changes
  │  4. Push branch
  │  5. Merge to main (or PR if you want review discipline)
  │  6. Delete branch
Enter fullscreen mode Exit fullscreen mode
# Daily solo workflow in practice:

# Start new work
git checkout -b feature/user-auth
# or: git switch -c feature/user-auth   # Newer syntax

# Make commits (small, focused, descriptive)
git add src/auth.js
git commit -m "Add JWT token generation and validation"

# More work...
git add src/middleware.js
git commit -m "Add auth middleware for protected routes"

# Sync with main before merging
git fetch origin
git rebase origin/main   # Clean linear history (vs merge = merge bubble)

# Push and merge
git push -u origin feature/user-auth
git checkout main
git merge feature/user-auth
git push
git branch -d feature/user-auth  # Clean up local branch
Enter fullscreen mode Exit fullscreen mode

Team Workflow: Feature Branches + PRs

main (protected) ──── only via PR merges ────→ production
                    ↗         ↑         ↖
              feature/A     feature/B   feature/C
                 (PR)         (PR)       (PR)

Rules:
1. Never commit directly to main
2. All changes go through Pull Requests
3. PRs require at least 1 approval
4. CI must pass before merge
5. Keep branches short-lived (< 2 days ideally)
Enter fullscreen mode Exit fullscreen mode

Branch Naming Convention

# Consistent naming makes branches self-documenting
feature/user-auth-login          # New feature
feature/#123-password-reset      # Feature linked to issue
bugfix/crash-on-null-input       # Bug fix
hotfix/security-patch-v1.2.1     # Urgent production fix
refactor/remove-deprecated-api   # Code cleanup
docs/update-readme               # Documentation
chore/update-dependencies        # Maintenance
release/v2.0.0                   # Version release
experiment/new-ui-layout         # Experimental (may be discarded)
Enter fullscreen mode Exit fullscreen mode

Commit Discipline: The Foundation of Everything

# ❌ Bad commits
git commit -m "fix"                          # Useless message
git commit -m "updated stuff"                # Vague
git commit -m "fix bug, add feature, refactor" # Multiple concerns
git commit -m "WIP"                          # Don't commit incomplete work
git commit -m "asdfghjkl"                    # Seriously?

# ✅ Good commits (Conventional Commits format)
git commit -m "feat: add user authentication with JWT"
git commit -m "fix: resolve crash when email is null"
git commit -m "docs: update API endpoint examples"
git commit -m "refactor: extract validation into shared module"
git commit -m "test: add coverage for payment processing"
git commit -m "chore: upgrade express to v4.21"
git commit -m "style: format code with prettier"
git commit -m "perf: cache database queries in user service"
git commit -m "revert: undo broken auth middleware change"

# Conventional Commits structure:
# <type>(<scope>): <subject>
#
# Types: feat | fix | docs | style | refactor | perf | test | build | ci | chore | revert
# Scope: optional, describes which module/area (auth, api, db, ui...)
# Subject: imperative mood, lowercase, no period at end

# Body (optional, add blank line after subject):
git commit -m "feat(auth): add OAuth2 Google login support

- Add /auth/google endpoint for initiating OAuth flow
- Add /auth/google/callback for handling callback
- Store Google user info in users table
- Generate JWT token on successful authentication

Closes #142"
Enter fullscreen mode Exit fullscreen mode

Handling Conflicts Like a Pro

# Scenario: You and teammate both edited the same file

# Step 1: Get latest main
git checkout main
git pull origin main

# Step 2: Rebase your feature branch onto latest main
git checkout feature/my-feature
git rebase main

# CONFLICT! Git marks conflicts like this:
# <<<<<<< HEAD (current: main's version)
# const authenticate = (user) => {
#   validateUser(user);
#   return generateToken(user);
# };
# =======
# const authenticate = (user) => {
#   if (!validateUser(user)) throw new AuthError();
#   return signToken(user.id);
# };
# >>>>>>> feature/my-feature (incoming: your version)

# Step 3: Resolve conflicts (pick best of both, or rewrite)
const authenticate = (user) => {
  if (!validateUser(user)) throw new AuthError(); // Keep your validation
  return generateToken(user);                      // Keep their function name
};

# Step 4: Mark as resolved and continue
git add src/auth.js          # Stage the resolved file
git rebase --continue        # Continue rebasing

# If it gets too messy, abort and try again
# git rebase --abort         # Go back to how things were

# Pro tip: use a merge tool for visual conflict resolution
git config --global merge.tool vscode  # or meld, kdiff3, etc.
git mergetool                   # Opens visual merge tool
Enter fullscreen mode Exit fullscreen mode

Rewriting History (When It's Safe)

# ⚠️ Only rewrite LOCAL history that hasn't been pushed/shared!

# Amend last commit (fix typo, add forgotten file)
git commit --amend -m "Better commit message"
# or: git add forgotten-file.js && git commit --amend --no-edit

# Squash last N commits into one (clean up WIP commits)
git rebase -i HEAD~3
# Editor opens, pick/squash/reword/drop/edit each commit:
# pick abc1234 Initial work
# squash def5678 Add more features  → squashed into previous
# drop ghi9012 Experiment that didn't work  → removed entirely

# Interactive rebase commands:
# p, pick = use commit as-is
# r, reword = use commit but edit message
# e, edit = use commit but stop for amending
# s, squash = combine with previous commit
# f, fixup = like squash but discard message
# d, drop = remove commit completely

# Reorder commits (move lines in interactive rebase editor)
# Split a commit (edit → reset HEAD~1 → make multiple commits)

# Fix author info (if you committed with wrong email)
git commit --amend --author="Correct Name <correct@email.com>"
# Or for multiple commits:
git rebase -i root~1  # Then mark each with 'edit' and:
# git commit --amend --author="..." && git rebase --continue
Enter fullscreen mode Exit fullscreen mode

Advanced Patterns

# Stash: Save work temporarily without committing
git stash                    # Save all working directory changes
git stash push -m "WIP: auth feature"  # With descriptive message
git stash list               # List all stashes
git stash pop                # Apply and remove most recent stash
git stash apply              # Apply but keep in stash list
git stash show -p            # Show diff of stashed changes
git stash drop                # Remove specific stash
git stash clear              # Remove ALL stashes
git stash push -p             # Interactively choose what to stash

# Cherry-pick: Apply specific commits from another branch
git cherry-pick abc1234       # Apply one commit
git cherry-pick abc1234 def5678  # Apply multiple commits
git cherry-pick --no-commit abc1234  # Apply to staging area only

# Bisect: Find which commit introduced a bug
git bisect start
git bisect bad                  # Current version has the bug
git bisect good v2.0.0          # This version was fine
# Git will checkout commits; you test each one:
git bisect good                 # This commit is fine
git bisect bad                  # This commit has the bug
# Eventually: abc1234 is the first bad commit
git bisect reset                # Done, return to original branch

# Worktree: Work on multiple branches simultaneously
git worktree add ../feature-a feature/branch-a
git worktree add ../hotfix hotfix/urgent-fix
# Now you have three checkouts without stashing/switching!
git worktree list               # Show all worktrees
git worktree remove ../feature-a  # Clean up

# Hooks: Automate quality checks
# .git/hooks/pre-commit (make executable):
#!/bin/bash
npm run lint || exit 1          # Block commit if lint fails
npm run typecheck || exit 1     # Block commit if types wrong

# .git/hooks/commit-msg (enforce conventional commits):
#!/bin/bash
# Check if message follows conventional commit format
if ! grep -qE "^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .+" "$1"; then
  echo "Invalid commit message! Use conventional commits format."
  exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Quick Reference

Daily commands I actually use:

git status                     # What's changed?
git diff                        # What exactly changed?
git log --oneline -10           # Recent history
git add -p                      # Stage chunks interactively
git commit -m "type: message"   # Commit with good message
git push                        # Send to remote
git pull --rebase              # Sync + rebase (clean history)
git checkout -b new-feature    # Start new work
git stash                       # Temporarily save work
git clean -fd                   # Remove untracked files (careful!)

Emergency commands:
git reset --hard HEAD~1         # Undo last commit (destructive!)
git reflog                      # Find lost commits (safety net!)
git checkout -b recovery abc1234 # Recover from reflog
git restore file.txt            # Undo local changes to one file
Enter fullscreen mode Exit fullscreen mode

What's your must-have Git alias or workflow trick?

Follow @armorbreak for more practical developer guides.

Top comments (0)