open atlas
↑ Back to track
Git, from zero to senior GIT · 04 · 04

Amend and interactive rebase

git commit --amend rewrites the last commit (new SHA); git rebase -i HEAD~N opens a todo list to reword, edit, squash, fixup, drop, or reorder commits before a PR. Both rewrite history — so the golden rule is: never rewrite commits others have already pulled.

GIT Middle ◷ 19 min
Level
FoundationsJuniorMiddleSenior

Your branch works, but the history is embarrassing: “wip”, “fix typo”, “actually fix it”, “fix the fix”. No reviewer wants to read that, and the commit messages tell no story. Git lets you reshape a messy branch into a clean, readable sequence before anyone sees it — fixing the last commit with --amend, or rewriting a whole run of commits with interactive rebase. The power comes with one ironclad rule about whose history you are allowed to rewrite.

By the end of this lesson you will be able to amend the last commit, run an interactive rebase to reword and squash commits, and state the golden rule that keeps history rewriting from wrecking your team.

Goal

After this lesson you can fix the last commit with git commit --amend, use git rebase -i HEAD~N with pick, reword, edit, squash, fixup, and drop to clean up a branch, abort a rebase safely, and apply the golden rule of rebasing.

1

git commit --amend replaces the last commit — it does not edit it in place. Use it to fix the most recent commit’s message, or to fold in a change you forgot:

git commit --amend -m "Add rate limiter with backoff"   # fix the message
# or: stage the forgotten file first, then amend to include it
git add src/limiter.js
git commit --amend --no-edit                              # keep the old message

Critically, amend creates a brand-new commit with a new SHA; the original is discarded (it lingers only in the reflog). That is why amend counts as rewriting history: the commit others might have is no longer the commit you now have.

2

git rebase -i HEAD~N opens a todo list for the last N commits. Interactive rebase is the workhorse for reshaping several commits at once:

git rebase -i HEAD~4    # edit the last 4 commits

Git opens an editor listing those commits oldest-first, each prefixed with the action pick. You change the action word per line (and may reorder the lines), save, and git replays the commits according to your instructions. Nothing is final until you save and close — and even then git rebase --abort undoes the whole operation.

3

The todo actions are a small, learnable vocabulary. The ones you will use constantly:

pick    <sha>  keep the commit as-is
reword  <sha>  keep the changes, edit the commit message
edit    <sha>  stop here so you can change the commit's content
squash  <sha>  merge into the previous commit, COMBINING both messages
fixup   <sha>  merge into the previous commit, DISCARDING this message
drop    <sha>  delete the commit entirely

Reordering is implicit: move a line up or down and the commit moves in history. squash and fixup are how four “fix typo” commits collapse into one clean commit; fixup is the quiet version that throws away the junk messages.

Why this works

Why bother cleaning history at all if the code is identical? Because history is documentation for the next engineer (often you). A reviewer reading ten “wip” commits cannot tell what each change accomplishes; a reviewer reading three commits — “Add parser”, “Add parser tests”, “Handle empty input” — can review each in isolation and trust git bisect and git blame later. Clean history is not vanity; it makes the codebase debuggable months from now.

4

The golden rule of rebasing: never rewrite commits others have already pulled. Amend and interactive rebase both replace commits with new SHAs. If those old commits were only ever local, no harm done. But if you have pushed and a teammate pulled, rewriting them makes your branch and theirs diverge — the same shared-history damage you saw with reset. So:

Rewrite freely:  local commits, or a feature branch nobody else has pulled
NEVER rewrite:   commits already pushed to a shared branch others build on

If a rebase goes sideways before you finish, back out cleanly:

git rebase --abort     # restore the branch to exactly its pre-rebase state
Worked example

Clean up a four-commit branch before opening a PR.

Your branch has: Add parser, wip, fix typo, tests. You want two tidy commits: the parser and its tests.

git rebase -i HEAD~4

The editor opens:

pick a1  Add parser
pick b2  wip
pick c3  fix typo
pick d4  tests

You rewrite it to squash the messy middle into the parser, and keep tests separate:

pick   a1  Add parser
fixup  b2  wip
fixup  c3  fix typo
reword d4  tests

Save. Git folds b2 and c3 into a1 (discarding their messages), then pauses on d4 to let you rename it to Add parser tests. The result is two clean commits with new SHAs. Because this branch was never pushed, rewriting it breaks nothing. Had you already pushed and a colleague had pulled, you would leave it alone — or coordinate a force-push very deliberately.

Common mistake

A frequent disaster: rebasing a shared branch and then running git push --force, which overwrites the remote and orphans everyone else’s matching commits. If you genuinely must force-push a rewritten personal branch, prefer git push --force-with-lease: it refuses to overwrite if the remote moved since you last fetched, catching the case where a teammate pushed in the meantime. Plain --force has no such safety check.

Check yourself
Quiz

You used `git commit --amend` to fix the last commit's message. What actually happened to that commit?

Recap

git commit --amend replaces the most recent commit — fixing its message or folding in forgotten changes — producing a new SHA. git rebase -i HEAD~N opens a todo list where pick, reword, edit, squash, fixup, drop, and reordering let you reshape several commits into a clean, reviewable history; git rebase --abort backs out safely. Both operations rewrite history, so obey the golden rule of rebasing: never rewrite commits others have already pulled — and prefer --force-with-lease over --force if you must push a rewritten personal branch. Next, the headline of this unit: changing a commit’s author and dates, where the same rewrite mechanics get applied to identity itself.

Practice

Start at the top. Tasks go easiest → hardest: recall a fact, apply it to a case, then a senior-level stretch. Open one, attempt it, then reveal.

recallapplystretch0 of 4 done

Something unclear?

Ask a question about this lesson. Questions are anonymous and go straight to the author to make the lesson better.

shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.