| name | git-rebase |
| description | Git interactive rebase, history rewriting, and advanced branching strategies. Use when cleaning up commit history before PR, splitting or squashing commits, fixing commit messages, reordering commits, or resolving complex rebase conflicts. Covers git rebase -i, reflog, filter-branch, and bisect combined with rebase workflows. |
Git Rebase — Craft a Clean History
Core Mental Model
Before rebase (merge commits clutter history):
A───M───A'───M'───A'' (M = merge commits)
After rebase (linear, readable):
A───A'───A''───A''' (no merge commits, one clean line)
Golden rule: Never rebase commits that have been pushed to a shared branch.
Interactive Rebase (git rebase -i)
How it works
git rebase -i HEAD~3
pick abc1234 Add user authentication
pick def5678 Fix typo in auth
pick ghi9012 Add password validation
pick → keep commit as-is
reword → keep commit, change message
edit → stop here, amend/rebase manually
squash → combine with previous commit
fixup → like squash, discard this commit's message
drop → remove commit
reorder→ move lines up/down
Example: Clean up a messy branch before PR
git rebase -i HEAD~5
pick a1b2c3d WIP: started auth
pick e4f5g6h WIP: auth working
pick i7j8k9l Fixed bug in auth (oops, went in wrong commit)
pick m1n2o3p Add password validation
pick q4r5s6t Final polish
# Change to:
pick a1b2c3d WIP: started auth
f i7j8k9l Fix bug in auth (squash into previous)
f e4f5g6h WIP: auth working (squash into first)
pick m1n2o3p Add password validation
r q4r5s6t Final polish: add complete auth flow
Result: 3 clean commits instead of 5 messy ones.
Common Operations
1. Squash consecutive commits
git rebase -i HEAD~3
2. Split a commit into multiple
git rebase -i HEAD~1
git reset HEAD~1
git add src/auth.go && git commit -m "Add auth package"
git add src/auth_test.go && git commit -m "Add auth tests"
git add src/middleware.go && git commit -m "Add auth middleware"
git rebase --continue
3. Reorder commits
git rebase -i HEAD~4
4. Edit an old commit message
git rebase -i HEAD~5
5. Drop a commit entirely
git rebase -i HEAD~5
6. Apply a commit from one branch onto another (rebase vs cherry-pick)
git cherry-pick abc1234
git checkout feature
git rebase main
Conflict Resolution During Rebase
git status
vim src/auth.go
git add src/auth.go
git rebase --continue
git rebase --abort
Rebasing with autosquash (auto-group fixup commits)
git commit --fixup abc1234
git rebase -i --autosquash main
Branching Strategies Compared
Git Flow (Heavy)
main ──────────────────────────── (production releases)
└ develop ──────────────────── (integration)
├─ feature/user-auth ──── (rebase onto develop, squash)
├─ feature/billing ──────
└─ release/1.4 ───────── (rebase, test, merge)
Trunk-Based Development (Light)
main ──●───●───●───●───●──●─── (everyone commits to main)
└─ feature/auth
└─ feature/billing
# Short-lived branches (< 1 day), rebase onto main frequently
Rebase Workflow
git checkout main && git pull --rebase
git checkout -b feature/auth
git add src/auth.go && git commit -m "Add JWT token generation"
git add src/auth_test.go && git commit -m "Test JWT token generation"
git fetch origin
git rebase -i origin/main
git push --force-with-lease
Reflog — Your Safety Net
git reflog
git checkout feature/auth
git reset --hard HEAD@{1}
git reflog | grep "abc123"
git cherry-pick abc1234
Advanced: filter-repo
For mass history rewriting (remove secrets, rename files across history):
pip install git-filter-repo
git filter-repo --path secret.txt --invert-paths --force
git filter-repo --path-rename old_name/:new_name/ --force
git filter-repo --mailmap author-script
⚠️ filter-repo rewrites history permanently. Always work on a fresh clone.
Rebase vs Merge — When to Use Each
| Situation | Use |
|---|
| Cleaning up local commits before PR | rebase -i |
| Bringing feature up to date with main | rebase |
| Integrating a finished feature branch | merge |
| Collaborative/shared branches | merge (never rebase) |
| Fast-forward only (clean history) | git merge --ff-only |
| Public/shared branch has bad commits | git revert (never rebase) |
| Long-running feature branch | Periodic rebase onto main |
Pre-PR Checklist
Before pushing and opening a PR:
□ Rebased onto latest target branch
□ Commits are atomic (one logical change per commit)
□ No "WIP" or "fix" commits (squash them)
□ Commit messages follow convention: type(scope): description
□ Force-with-lease used (not force push)
□ Tests pass locally
□ History is readable as a story
Commit Message Convention
type(scope): short description (50 chars max)
Optional longer description (wrap at 72 chars)
Footer: references/issues
Types:
feat: new feature
fix: bug fix
refactor: code change that neither fixes a bug nor adds a feature
test: adding or correcting tests
docs: documentation only
chore: maintenance tasks (deps, config)
perf: performance improvement
Examples:
feat(auth): add JWT token generation and validation
fix(checkout): prevent negative quantity in cart
refactor(orders): extract payment service from order controller
test(api): add property-based tests for order serialization
When to Trigger This Skill
- Cleaning up commit history before PR
- Interactive rebase, squash, reorder, or split commits
- Rebase conflict resolution
- Git history archaeology (who wrote this, why)
- git reflog to recover from mistakes
- filter-repo for mass history rewriting
- Git workflow advice (rebase vs merge)
- Fixing commit messages after push
Last updated: 2026-03-28