Git & GitHub Mastery: Workflows & CI/CD
Back to Real-World Git Workflows

Scenario 3 — Interactive Rebase Cleanup

Clean up a messy commit history before opening a PR. Squash WIPs, reword messages, drop a bad commit.

36 minutesAssignment
🎯 Free Guest Mode: You are learning for free. Sign in to save your completion progress and quiz answers.

The brief

Take a branch with messy commits and clean it up using interactive rebase. The standard "polish before PR" workflow.

Step 1: Create a messy branch (10 min)

mkdir rebase-drill && cd rebase-drill
git init
echo "# Project" > README.md
git add . && git commit -m "Initial"

# Pretend it's main
git switch -c feature/login

# Messy commits
echo "function login() {}" > login.js
git add . && git commit -m "Add login function"

echo "function login(user, pass) {}" > login.js
git commit -am "WIP"

echo "function login(user, pass) { console.log('debug') }" > login.js
git commit -am "WIP add debug"

echo "function login(user, pass) { return validate(user, pass) }" > login.js
git commit -am "fix login"

echo "// Login module" > login.js
echo "function login(user, pass) { return validate(user, pass) }" >> login.js
git commit -am "Add comment"

echo "TODO: write tests" > tests.js
git add . && git commit -m "test stub"

git log --oneline
# Should show 6 commits with messy messages

Step 2: Interactive rebase (15 min)

git rebase -i main

Editor opens with:

pick abc1 Add login function
pick abc2 WIP
pick abc3 WIP add debug
pick abc4 fix login
pick abc5 Add comment
pick abc6 test stub

Edit to clean up:

pick abc1 Add login function
fixup abc2 WIP
fixup abc3 WIP add debug
fixup abc4 fix login
fixup abc5 Add comment
pick abc6 test stub

Save and close. Git replays:

  • abc1 stays.
  • abc2, abc3, abc4, abc5 are squashed INTO abc1 (their messages discarded).
  • abc6 stays.

Result: 2 clean commits.

git log --oneline
# def4 (HEAD -> feature/login) test stub
# def5 Add login function

Step 3: Reword commit messages (10 min)

git rebase -i main
reword def5 Add login function
reword def4 test stub

Git prompts for each message in turn. Edit them:

Add login function with validation

Implements basic login: takes user and password, calls validate().
Add placeholder for login tests

TODO: write actual tests for the login function.

Now your commits have meaningful messages.

Step 4: Drop a commit (5 min)

Add a bad commit:

echo "secret_key=abc123" > .env
git add . && git commit -m "Add config (FORGOT THIS WAS A SECRET)"

Realize the mistake. Drop it via rebase:

git rebase -i main

Find the bad commit; change pick to drop:

pick xyz Add login function
pick xyz test stub
drop xyz Add config (FORGOT THIS WAS A SECRET)

Save. The commit and its changes are gone.

Verify:

git log --oneline       # no bad commit
ls                      # no .env file

Step 5: Reorder commits (5 min)

Add a few more commits:

echo "login_button" > ui.js
git add . && git commit -m "Add login UI"

echo "throttle login" > rate_limit.js
git add . && git commit -m "Add login rate limit"

Rebase to reorder:

git rebase -i main

Change:

pick a Add login function
pick b test stub
pick c Add login UI
pick d Add login rate limit

To (reordering so rate limit comes before UI):

pick a Add login function
pick d Add login rate limit
pick c Add login UI
pick b test stub

If commits don't conflict, reorder works cleanly. If they do, resolve as usual.

Step 6: Autosquash workflow

Make some commits, then mark fixups for an earlier commit:

echo "// improved" >> login.js
git commit --fixup=<sha-of-earlier-login-commit>

echo "// more notes" >> login.js
git commit --fixup=<same-sha>

git log --oneline
# Shows: fixup! Add login function (etc.)

Auto-arrange in rebase:

git rebase -i --autosquash main

Git pre-arranges the fixups next to their targets in the editor. You just save.

Deliverables

Submission contract: upload CLEANUP.md (before/after git log --oneline, which rebase commands you used, when --autosquash helps).

100-pt rubric: messy branch created (10) / squash+fixup merged WIP into clean commits (25) / reword produced meaningful messages (20) / drop removed the secret commit (20) / reorder + --autosquash demonstrated (25).

upload CLEANUP.md (before/after git log --oneline, which rebase commands you used, when --autosquash helps).

messy branch created (10) / squash+fixup merged WIP into clean commits (25) / reword produced meaningful messages (20) / drop removed the secret commit (20) / reorder + --autosquash demonstrated (25).

upload CLEANUP.md (before/after git log --oneline, which rebase commands you used, when --autosquash helps).

messy branch created (10) / squash+fixup merged WIP into clean commits (25) / reword produced meaningful messages (20) / drop removed the secret commit (20) / reorder + --autosquash demonstrated (25).

  • Repository with clean commit history (2-4 atomic commits, good messages).
  • A CLEANUP.md describing:
    • The before-and-after.
    • What you used (squash, fixup, drop, reword, edit, reorder).
    • When --autosquash is useful.

What you'll learn

  • The interactive rebase editor and commands.
  • squash vs fixup (fixup discards the message).
  • Dropping a commit via drop or deleting the line.
  • Rewording vs editing (reword = message only; edit = stop for changes).
  • --autosquash + --fixup=SHA for iterative cleanup.
  • The "polish before PR" mindset.

Stretch

  • Try edit to actually split one commit into two (use git reset to un-commit, then commit selectively).
  • Use --root to rebase ALL commits including the first.
  • Practice on a branch with merge commits (use --rebase-merges).

Track your learning progressFree

Sign in or enroll free to mark this assignment as complete, save your progress, and earn certificates.