I've lost work to bad Git commands exactly 3 times in my career. Each time, I discovered a Git feature that would have saved me.
Here are the 5 commands I wish someone had shown me on day one.
1. git reflog — Your Undo Button for Everything
Deleted a branch? Force-pushed the wrong thing? git reflog shows EVERY action Git recorded — even ones that don't appear in git log.
# See everything you've done
git reflog
# Output:
# abc1234 HEAD@{0}: commit: broke everything
# def5678 HEAD@{1}: commit: working perfectly ← go back here
# ghi9012 HEAD@{2}: checkout: moving from main to feature
# Restore to the working state
git reset --hard HEAD@{1}
The story: I once ran git reset --hard on the wrong branch. 3 days of work — gone. Then a senior dev showed me git reflog. Everything was still there. Git never truly deletes anything (for ~90 days).
When to use it: After any destructive operation (reset, rebase, force push, branch delete).
2. git stash --include-untracked — Save EVERYTHING
Plain git stash ignores new files. This bit me when I stashed mid-feature, switched branches, and came back to find my new files were gone.
# This misses new files:
git stash
# This saves EVERYTHING — tracked, modified, AND new files:
git stash --include-untracked
# Or the short form:
git stash -u
# See what's stashed:
git stash list
git stash show -p stash@{0}
# Restore:
git stash pop
Pro tip: Name your stashes so you remember what they contain:
git stash push -u -m "WIP: payment integration, waiting for API key"
3. git bisect — Find the Bug in 7 Steps (Not 700)
Something broke between version 1.0 and now. There are 700 commits in between. git bisect uses binary search to find the exact commit.
# Start bisecting
git bisect start
# Mark current (broken) as bad
git bisect bad
# Mark a known good commit
git bisect good v1.0
# Git checks out a middle commit. Test it.
# If it works:
git bisect good
# If it's broken:
git bisect bad
# After ~7 steps (log2 of 700), Git tells you the EXACT commit that broke it
# Done? Reset:
git bisect reset
Automate it:
# Run a test script automatically
git bisect start HEAD v1.0
git bisect run python test_payment.py
# Git finds the breaking commit WITHOUT any manual testing
4. git worktree — Multiple Branches at Once
Ever needed to check something on main while deep in a feature branch? Most people stash → checkout → stash pop. There's a better way.
# Create a separate working directory for main
git worktree add ../project-main main
# Now you have two directories:
# ./project ← your feature branch
# ./project-main ← main branch
# Work on both simultaneously. No stashing.
# When done:
git worktree remove ../project-main
When I use this: Code reviews. I keep my feature branch open in one terminal and the PR branch in another. No context switching.
5. git cherry-pick — Steal One Commit From Anywhere
Sometimes you need ONE commit from another branch. Not a merge. Not a rebase. Just that one fix.
# Find the commit hash on the other branch
git log other-branch --oneline | head -5
# Pick it into your current branch
git cherry-pick abc1234
# Pick multiple commits:
git cherry-pick abc1234 def5678
# Pick without committing (stage only):
git cherry-pick --no-commit abc1234
Real scenario: A bug fix was committed to develop but we needed it in release immediately. Cherry-pick, push, done. No merge, no risk of pulling in unfinished features.
Bonus: My .gitconfig Safety Net
[alias]
undo = reset --soft HEAD~1
unstage = reset HEAD --
last = log -1 HEAD --format='%h %s'
save = stash push -u -m
branches = branch -a --sort=-committerdate
Now git undo safely undoes the last commit (keeps changes staged). No more panicking.
Which Git commands have saved your work? Or which ones have destroyed it? I want to hear your horror stories 👇
More from me: 10 Dev Tools I Use Daily | 77 Scrapers on a Schedule | 150+ Free APIs
Top comments (0)