
Git Good: Version Control Strategies That Would Not Make Your Team Hate You
You’ve been there: staring at a Git conflict so complex it looks like someone encrypted your code. Or maybe you’re the teammate who just pushed a 10,000-line commit titled “fixes” directly to main. Perhaps you’ve uttered the dreaded phrase, “I’ll just delete the repo and clone it again.”
It’s time to stop being a Git disaster and start being a Git master. Let’s dive into version control strategies that will make your life easier and keep your teammates from plotting your demise.
Why Most Git Workflows Are a Dumpster Fire
The average developer’s Git strategy:
- Make 73 unrelated changes
- Realize they haven’t committed in 8 hours
- Panic-commit with message “WIP”
- Force-push when things get weird
- Wonder why nobody wants to code review their PRs
Sound familiar? Let’s fix that.
Commit Like You Give a Damn
The Art of the Atomic Commit
Atomic commits focus on a single change, making your history browsable and your changes reviewable:
# BAD: Giant commit of doom
git add .
git commit -m "Fixed stuff"
# GOOD: Logical, separate commits
git add src/components/Button.js
git commit -m "Fix Button component focus state for accessibility"
git add src/utils/validation.js
git commit -m "Add email format validation for registration form"
Commit Messages That Actually Help
Your future self and teammates need more context than “updates”:
# Structure your commit messages like this:
Fix user authentication timeout on slow connections
- Increases token expiration window from 10s to 30s
- Adds automatic retry with exponential backoff
- Fixes issue #1337 reported by premium customers
The first line is your commit title (keep it under 50 characters). Then add a blank line followed by details.
Branching Strategies That Won’t Break Everything
Git Flow for Larger Projects
Git Flow creates a structured process with these branches:
main
- Production code onlydevelop
- Integration branch for featuresfeature/xyz
- New functionalityhotfix/xyz
- Emergency production fixesrelease/xyz
- Preparing for a release
# Starting a new feature
git checkout develop
git checkout -b feature/amazing-thing
# Working on hotfixes
git checkout main
git checkout -b hotfix/critical-payment-bug
GitHub Flow for Simpler Projects
For smaller teams, GitHub Flow simplifies things:
- Branch from
main
- Develop your feature
- Open a PR
- Review and discuss
- Deploy/test
- Merge to
main
git checkout -b descriptive-feature-name
# Make changes
git push -u origin descriptive-feature-name
# Open PR through GitHub interface
Pull Requests That People Actually Want to Review
A good PR is a joy to review. A bad one is digital torture.
The Anatomy of a Review-Friendly PR
Keep PRs focused and reasonably sized:
- 200-400 lines changed is ideal
- One logical feature or fix
- Clear description of what and why
- Screenshots for UI changes
- Links to related issues
## What this PR does
Adds password strength validation to the signup form
## Why it's needed
Users were creating weak passwords, leading to account security issues
## How it works
- Uses zxcvbn library to calculate password entropy
- Shows real-time feedback as user types
- Requires minimum score of 3/5 to enable submit button
## Screenshots
[Weak password state]
[Strong password state]
## Testing done
- Unit tests for validation logic
- E2E tests for form submission
- Manual testing across Chrome/Firefox/Safari
Handling Feedback Like a Pro
When receiving comments:
- Thank reviewers (they’re helping you!)
- Address every comment (even if just to explain why you’re not changing something)
- Make requested changes in new commits for easier re-review
- Use GitHub’s suggestion feature for simple changes
Dealing With the Inevitable Git Disasters
You Committed to the Wrong Branch
# Don't panic! This is easy to fix
git cherry-pick <commit-hash> # Apply the commit to your current branch
git checkout previous-branch
git reset --hard HEAD~1 # Remove the commit from old branch
Your Main Branch Is Broken
# Find the last working commit
git log
# Create a new branch from that commit
git checkout -b recovery-branch <last-working-commit-hash>
# Cherry-pick good changes
git cherry-pick <good-commit-hash>
# Once fixed, force-update main (BE CAREFUL)
git checkout main
git reset --hard recovery-branch
git push --force-with-lease origin main
Only use --force-with-lease
after communicating with your team!
The “Oh Crap I Didn’t Mean to Commit That” Moment
# Accidentally committed secrets or large files?
# Option 1: Fix the last commit
git reset --soft HEAD~1
# Remove the problematic files
git add .
git commit -m "Your original message without the bad stuff"
# Option 2: For sensitive data already pushed
# Use BFG Repo Cleaner or git-filter-branch
# Then force push (after warning team)
Advanced Git Techniques That Make You Look Like a Wizard
Interactive Rebasing for Clean History
Squash related commits and clean up before merging:
git rebase -i HEAD~5 # Interactive rebase of last 5 commits
# You'll see an editor with options:
# pick, squash, fixup, reword, etc.
Git Hooks for Consistency
Set up pre-commit hooks to enforce standards:
# .git/hooks/pre-commit
#!/bin/sh
npm run lint && npm test
Git Aliases for Efficiency
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
Now git st
works instead of git status
!
Automating With GitHub Actions
# .github/workflows/pr-checks.yml
name: PR Checks
on:
pull_request:
branches: [ main, develop ]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check commit message format
run: |
bash .github/scripts/validate-commits.sh
Git Etiquette: Don’t Be That Person
The Unwritten Rules of Git
- Never force push to shared branches
- Don’t rewrite history after sharing
- Don’t leave hanging pull requests
- Credit co-authors when pair programming
- Keep your local repo updated
# Before starting work each day
git checkout main
git pull
git checkout your-branch
git rebase main
Resolving Conflicts Like an Adult
# When you get a merge conflict
git status # See which files are conflicted
code path/to/conflicted/file.js # Open in editor
# Look for conflict markers <<<<<<< HEAD
# Fix the conflicts manually
git add path/to/conflicted/file.js
git rebase --continue # If rebasing
# or
git merge --continue # If merging
The Ultimate Git Cheat Sheet
Daily Workflow
# Start the day
git pull
# Create a new feature branch
git checkout -b feature/amazing-stuff
# Make small, focused commits
git add file1.js file2.js
git commit -m "Implement feature X"
# Push to remote
git push -u origin feature/amazing-stuff
# Create PR via GitHub interface
# Update with changes from main
git checkout main
git pull
git checkout feature/amazing-stuff
git rebase main
git push --force-with-lease
Helpful Commands
# See what you're about to commit
git diff --staged
# See changes in a file
git log -p filename
# Discard unstaged changes
git checkout -- filename
# See commit history with graph
git log --oneline --graph --decorate
# Stash changes temporarily
git stash
git stash pop
# Blame (who changed what)
git blame filename
Conclusion
Git is a powerful tool that can either make your development process smooth or turn it into a nightmare—and the difference often comes down to discipline and good habits.
Remember:
- Small, atomic commits
- Descriptive messages
- Focused branches
- Respect shared history
- Clear pull requests
Master these practices, and you’ll not only avoid Git disasters but also become the teammate everyone wants to work with. Your future self will thank you when you’re trying to figure out why something was changed six months from now.
Now go forth and Git Good! (But please, no more commits titled “stuff”.)