A clean, linear Git history with meaningful commits, rebased branches, and the ability to find exactly when a bug was introduced using git bisect.
git stash — Save Work Without Committing
You're mid-feature when someone asks you to fix an urgent bug. You don't want to commit half-done work. git stash saves your changes temporarily so you can switch context.
# You have uncommitted changes
git status
# Changes not staged: main.py
# Stash them
git stash push -m "WIP: streaming responses"
# Now working tree is clean — switch branches, fix the bug
git checkout main
git checkout -b fix/urgent-bug
# ... fix the bug, commit, merge ...
# Return to your feature branch
git checkout feature/streaming
# Restore your stashed work
git stash pop
# See all stashes
git stash list
# stash@{0}: On feature/streaming: WIP: streaming responsesgit rebase — Linearize History
Rebase replays your branch's commits on top of the latest main. This keeps history linear and avoids ugly merge commits. Use it before opening a PR.
# You're on feature/streaming, main has new commits
git fetch origin
git rebase origin/main
# Successfully rebased and updated refs/heads/feature/streaming
# Interactive rebase: edit, squash, or reorder commits
git rebase -i HEAD~3
# Opens editor showing last 3 commits:
# pick a1b2c3d Add streaming to API
# pick d4e5f6a Fix typo in comment
# pick g7h8i9j Fix another typo
# Change 'pick' to 'squash' (or 's') to combine commitsNever rebase shared branches. Only rebase branches that exist only on your machine or that nobody else has pulled. Rebasing rewrites history, which causes problems for collaborators.
Reading History and Finding Bugs
Git's log is a searchable history of every change. Learn to read it and you can find the exact commit that introduced any bug.
# Pretty one-line log with graph
git log --oneline --graph --all
# Search commits by message
git log --oneline --grep="claude"
# See what changed in a specific commit
git show a1b2c3d
# Find which commit introduced a bug (binary search)
git bisect start
git bisect bad HEAD
# Mark a known-good commit
git bisect good a1b2c3d
# Git checks out a middle commit, you test it
git bisect good # or: git bisect bad
# Git narrows it down — repeat until it finds the culprit
git bisect reset # when donecherry-pick and Undo Mistakes
Cherry-pick copies a single commit from one branch to another. Undo commands let you fix mistakes without panic.
# Copy a specific commit to current branch
git cherry-pick a1b2c3d
# Undo the last commit, keep changes staged
git reset --soft HEAD~1
# Undo the last commit, keep changes unstaged
git reset --mixed HEAD~1
# Undo a pushed commit safely (creates a new "undo" commit)
git revert HEAD
git push
# See where a line of code came from (who wrote it)
git blame main.pyRule: Use git revert for pushed commits, git reset for local-only commits. Revert is safe because it adds a new commit — it doesn't rewrite history.
What You Learned Today
- Used git stash to switch context without losing work
- Rebased a feature branch to keep history linear
- Searched Git history to find when a specific change was made
- Used cherry-pick to move individual commits and revert to undo mistakes
Go Further on Your Own
- Use git bisect to find which commit broke a test in a demo repo
- Write a bash alias for your favorite git log format
- Practice interactive rebase to squash 3 small 'fix typo' commits into one
Nice work. Keep going.
Day 5 is ready when you are.
Continue to Day 5Want live instruction and hands-on projects? Join the AI bootcamp — 3 days, 5 cities.