DEV Community

Alex Chen
Alex Chen

Posted on

The Git Workflow That Saved My Sanity as a Solo Developer

The Git Workflow That Saved My Sanity as a Solo Developer

After years of trial and error, this is the workflow I use for every project.

Branch Strategy: Trunk-Based Development

main (always deployable)
  │
  ├── feature/user-auth          (short-lived branch)
  │   └── merge → main
  │
  ├── fix/login-bug              (hotfix)
  │   └── merge → main
  │
  └── experiment/ai-suggestions  (might be abandoned)
      └── only merge if it works out
Enter fullscreen mode Exit fullscreen mode
# Start new work from latest main
git checkout main
git pull origin main
git checkout -b feature/my-feature

# Work, commit, work, commit...

# Push branch for review / backup
git push -u origin feature/my-feature

# When done:
# Option A: Merge to main
git checkout main
git pull origin main
git merge --no-ff feature/my-feature  # Preserve history
git push origin main

# Option B: Squash into one clean commit (for messy WIP branches)
git checkout main
git pull origin main
git merge --squash feature/my-feature
git commit -m "Feature: Add user authentication"
git push origin main
Enter fullscreen mode Exit fullscreen mode

My Commit Convention

# Format: type(scope): subject
# body (optional)
# footer (optional)

feat(auth): add OAuth2 Google login

- Implement Google OAuth2 flow
- Create/update user on first login
- Store refresh token for API access

Closes #123
Enter fullscreen mode Exit fullscreen mode

Types I Use

Type When
feat New feature
fix Bug fix
refactor Code restructuring (no behavior change)
docs Documentation only
style Formatting, semicolons, etc. (no logic change)
perf Performance improvement
test Adding/updating tests
chore Build, config, dependencies
revert Revert a previous commit

Pre-Commit Hook (Catches Mistakes Before They Happen)

// .husky/pre-commit (or package.json "lint-staged" config)
{
  "lint-staged": {
    "*.{js,ts}": [
      "eslint --fix",
      "prettier --write",
      "git add"
    ],
    "*.{json,md,yml,yaml}": [
      "prettier --write",
      "git add"
    ],
    "*.{css,scss,html}": [
      "stylelint --fix",
      "git add"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode
# Install:
npm install -D husky lint-staged prettier eslint
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"

# Now every commit is automatically formatted and linted!
Enter fullscreen mode Exit fullscreen mode

Interactive Staging (Commit Only What You Want)

# See what changed
git status

# Stage specific files
git add src/utils.js src/api.js

# Or stage parts of a file (hunk by hunk)
git add -p

# The interactive prompt:
# y = stage this hunk
# n = don't stage this hunk
# s = split into smaller hunks
# e = edit this hunk manually
# ? = help

# Review before committing
git diff --cached     # Shows exactly what will be committed
git commit             # Only staged changes are included
Enter fullscreen mode Exit fullscreen mode

The Undo Toolkit

# Modified a file but want to start over?
git checkout -- filename       # Discard working directory changes

# Committed too early (want to modify the last commit)?
git commit --amend            # Edit message or add more changes

# Committed to wrong branch?
git reset HEAD~1               # Undo commit, keep changes unstaged
git checkout correct-branch
git add .
git commit

# Pushed something you shouldn't have?
git revert SHA                 # Creates a NEW commit that undoes the change
# Safer than force-push!

# Need to update a PR after review?
git commit -m "fix: address reviewer feedback"
git push                      # Just push new commits (don't rebase after pushing!)
Enter fullscreen mode Exit fullscreen mode

Keeping History Clean

# Before merging a feature branch, clean up the history:

# 1. See recent commits
git log --oneline -10

# 2. Interactive rebase (squash WIP commits)
git rebase -i HEAD~5

# In the editor that opens:
pick abc1234 WIP: started work
squash def5678 WIP: more stuff
squash ghi9010 fix typo
pick jkl1123 add tests
pick mno3456 final cleanup

# Change squash to combine WIP commits into one meaningful commit:
pick abc1234 feat: implement user auth
pick jkl1123 test: add unit tests for auth
pick mno3456 style: format code

# Save and exit → clean history!
Enter fullscreen mode Exit fullscreen mode

Working With Others (or Across Machines)

# Before starting work ALWAYS:
git pull origin main        # Get latest changes

# If there are conflicts after pulling:
# 1. Don't panic
# 2. Open each conflicted file
# 3. Look for <<<<<<< HEAD (your changes) and ======= (their changes)
# 4. Decide which to keep (or combine both)
# 5. Remove the conflict markers
# 6. git add <resolved-file>
# 7. git continue (if using rebase) or git commit (if using merge)

# Quick conflict resolution tip:
# Accept yours:   git checkout --ours filename
# Accept theirs: git checkout --theirs filename
# Then:           git add filename && git continue
Enter fullscreen mode Exit fullscreen mode

My Daily Git Commands

# Morning: check status of everything
git status                    # What's changed?
git log --oneline -5         # Recent commits
git branch -vv                # All branches and their status

# During work:
git diff                      # Unstaged changes
git diff --cached             # Staged changes (what will be committed)
git stash                     # Save work temporarily
git stash pop                 # Get it back

# Before pushing:
git log origin/main..HEAD --oneline  # What am I about to push?
git diff --stat origin/main..HEAD   # How much changed?

# After pushing:
git push origin main
Enter fullscreen mode Exit fullscreen mode

Aliases That Save Me Time

[alias]
  co = checkout
  br = branch
  ci = commit
  st = status -sb
  lg = log --oneline --graph --all --decorate
  unstage = reset HEAD --
  amend = commit --amend --no-edit
  prune-all = !git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d
  save = !git add -A && git stash
  pop = stash pop
  undo = reset HEAD~1
  diffstat = diff --stat
  recent = log --oneline -10
Enter fullscreen mode Exit fullscreen mode

What's your favorite Git workflow tip? Anything here you'd do differently?

Follow @armorbreak for more developer content.

Top comments (0)