Previously, in Part 7, we opened our work to the world with pull requests and code review — and learned that a good review is a conversation, not a courtroom.
For seven parts we have treated history as sacred. Every commit was a photo glued into the album, forever. Today I am going to let you in on a secret: Git also has an editing room. You can reorder the photos, merge three blurry shots into one good one, and even copy a single photo into a completely different album. It feels like time travel with editing rights — because it is. Which is exactly why we start with the one rule that keeps everybody safe.
Careful: This is the Golden Rule of rewriting history: never rewrite commits that other people already have. If a commit has been pushed and a teammate may have pulled it, treat it as glued down. Everything in this post is for your local drafts — the commits only you have seen. Rewrite your drafts, never the shared album.
The appetizer: git stash
Before the big tools, a small one you will use weekly. Picture this: you are halfway through a new feature in the workshop's ClinicApp — files half-edited, nothing compiles — when a message arrives: "the patients page is broken, can you look right now?" You cannot commit this mess, and you cannot switch branches carrying it either. So you put it in your pocket.
git stash
git switch master
# fix the urgent thing, commit it, breathe out
git switch feature/patient-photos
git stash pop
git stash scoops up all your uncommitted changes and stores them safely away,
leaving your working directory clean. git stash pop puts them right back, as
if the interruption never happened. If you ever forget what is in your pocket:
git stash list
stash@{0}: WIP on feature/patient-photos: 3f2a1c9 Add the new-patient form with validation
Think of the stash as a pocket, not a filing cabinet. Things get forgotten in pockets. If the work matters for more than an hour or two, make a real commit on a branch instead — you now know how to tidy it up later, which is where we are headed next.
The editing room: interactive rebase
Here is an honest picture of how real people code: three messy commits with messages like
"wip", then "fix typo", then "actually works now". There is nothing wrong with committing
that way — small, frequent saves are a good habit. The trick is tidying them up
before anyone sees them. Let's practice in your clone of the workshop repo. Make a practice
branch, open README.md, and build the mess on purpose: add a line and commit,
adjust the wording and commit, finish the thought and commit.
git switch -c practice/rebase
# edit README.md, then:
git commit -am "wip"
# edit again:
git commit -am "fix typo"
# one more:
git commit -am "actually works now"
Now open the editing room. We want to revisit the last three commits:
git rebase -i HEAD~3
Git opens your editor with a little todo list. Do not panic — it is just text, and nothing happens until you save it:
pick a1b2c3d wip
pick d4e5f6b fix typo
pick f7c8d9e actually works now
# Commands:
# p, pick = use commit as-is
# r, reword = use commit, but edit the commit message
# s, squash = use commit, but meld into previous commit
# d, drop = remove commit entirely
Read it top to bottom: oldest commit first. Each line is an instruction, and you edit the
first word to change the plan. pick means "keep as-is", reword
means "keep, but let me fix that embarrassing message", squash means "merge
this photo into the one above it", and drop deletes the commit entirely. We
want all three melded into one presentable commit, so change it to:
pick a1b2c3d wip
squash d4e5f6b fix typo
squash f7c8d9e actually works now
Save and close. Git immediately opens a second editor asking for the message of the new,
combined commit. Delete the three old messages and write one honest line — something like
"Add a notes section to the workshop README". Save, close, and run
git log --oneline: three blurry shots have become one clean photo. That is the
whole skill. Before every pull request, I take thirty seconds in this editor so the
reviewer sees a story instead of a diary.
Careful: after a rebase, the commits have new hashes. They are new photos of the same work — which is precisely why the Golden Rule exists. Squash your local drafts freely; never rebase anything you have already pushed for others.
Rebase or merge? An honest answer
There is a second use of rebase: instead of merging master into your feature
branch, you can rebase your feature branch onto master. Git lifts your commits off,
moves them to the tip of master, and replays them one by one — as if you had started your
work this morning. The result is a perfectly straight timeline. A merge, by contrast, keeps
the little bubble that says "these two lines of work happened in parallel and joined here."
So which is right? Both. A merge is a truthful timeline; a rebase is a straightened one that never quite happened. Teams genuinely choose either — the only wrong answer is mixing them at random.
| Question | Merge | Rebase |
|---|---|---|
| What history shows | What really happened, bubbles and all | A tidy straight line that never quite happened |
| Safe on shared branches? | Yes, always | Only before you push |
| Reading the log later | Can get noisy on busy projects | A pleasure |
| Conflicts | Resolved once, in the merge | May reappear per replayed commit |
Cherry-pick: copying one photo
One last tool for the kit. Suppose that on your feature branch you fixed a small but real bug in the PatientCard component. The branch itself will not be ready for days, but master needs that one fix today. Cherry-pick copies a single commit onto another branch:
git log --oneline feature/patient-photos
# spot the fix, say a1b2c3d
git switch master
git cherry-pick a1b2c3d
Careful: the copy is a brand-new commit with a brand-new hash — same change, different fingerprint. When the feature branch merges later you may spot the "duplicate" in history. Git usually reconciles it quietly, and it is a small price for shipping a fix fast.
Tip: while you experiment with all of this, keep
git log --oneline --graph --all handy. It draws every branch, every
squash, and every cherry-pick as a little ASCII map — the single best way to see
what a rebase actually did.
Next time: the rescue kit
A fair question is probably nagging you: "what if I rebase myself off a cliff?" What if you squash the wrong commits, drop a line you needed, or delete a branch entirely? Here is the wonderful truth we will prove in Part 9: in Git, almost nothing is ever truly lost. Bring your climbing rope — next time we go rescue some commits.