Git Doesn't Have to Be Complicated
GitFlow, GitHub Flow, trunk-based development... lots of opinions out there. When you're working solo, you need something simpler.
Here's a workflow I've used for years.
The Setup
Two types of branches:
main- always works, always deployablefeature/somethingorfix/something- your work in progress
That's it. No develop branch, no release branches.
Starting Work
git checkout main
git pull
git checkout -b feature/user-profiles
Do your work. Commit often:
git add -A
git commit -m "Add profile page layout"
# more work
git commit -m "Add avatar upload"
# more work
git commit -m "Connect profile form to backend"
Writing Good Commit Messages
Future you will thank present you.
Bad:
fixed stuff
updates
wip
Good:
Add avatar upload to profile page
- Accept jpg, png, gif up to 2MB
- Store in S3 with public access
- Generate thumbnail on upload
The format:
- Short summary (what you did)
- Blank line
- Details if needed (why, how, gotchas)
Finishing a Feature
Before merging, sync with main and clean up:
git checkout main
git pull
git checkout feature/user-profiles
git rebase main
If there are conflicts, fix them. Then:
git checkout main
git merge feature/user-profiles
git push
git branch -d feature/user-profiles
The Rebase Question
git merge keeps all your messy commits. git rebase lets you clean them up first.
I usually squash related commits before merging:
git rebase -i HEAD~5 # Interactive rebase last 5 commits
Change pick to squash for commits you want to combine. Rewrite the message. Now your feature is one or two clean commits.
Tagging Releases
When you deploy something:
git tag -a v1.4.0 -m "Release 1.4.0 - user profiles"
git push origin v1.4.0
Now you can always get back to this exact code:
git checkout v1.4.0
Useful Shortcuts
Add to ~/.gitconfig:
[alias]
st = status
co = checkout
br = branch
ci = commit
unstage = reset HEAD --
last = log -1 HEAD
undo = reset --soft HEAD~1
Now git st instead of git status, etc.
Fixing Mistakes
Committed but didn't push? Undo it:
git reset --soft HEAD~1
# Your changes are back, uncommitted
Messed up a file?
git checkout -- filename.php
Need to find a lost commit?
git reflog
# Shows recent HEAD positions, find your commit hash
git checkout abc123
Push Often
Your laptop could die. Push to remote at least daily:
git push origin HEAD
I push after finishing any meaningful chunk of work. Small feature done? Push. Fixed a bug? Push.
The Whole Flow
- Pull main
- Create feature branch
- Work, commit often
- Rebase on main (fix conflicts)
- Squash if needed
- Merge to main
- Push
- Delete feature branch
- Tag if it's a release
Simple, clean history, easy to understand what happened and when.
