Autosquash — Fixup & Squash Automation
Mark karo, phir autosquash karo. Professional history bina manual mehnat ke.
You commit feat: add login. Then you find a typo. You commit fix: typo in login. Then another small issue: fix: forgot semicolon. Before your PR, you interactive-rebase, change the fix commits to fixup, and they merge into the original commit.
This is the correct workflow. But it is tedious if you do it many times per day.
Every fix requires: git rebase -i, find the fix commit in the list, change pick to fixup, save the file, close the editor. Five steps per fix. If you have 5 fix commits, that is 25 manual steps.
There is a better way: mark commits as fixups WHEN you create them, then let Git auto-arrange them during rebase. No manual editing needed.
# The manual workflow (tedious)
git commit -m "feat: add login"
git commit -m "fix: typo in login"
git commit -m "fix: forgot semicolon"
# ... more commits ...
# Before PR:
git rebase -i HEAD~5
# Manually change:
# pick abc123 feat: add login
# fixup def567 fix: typo in login ← manually changed
# fixup ghi890 fix: forgot semicolon ← manually changed
# Save, close editor, Git squashes them
# This works but is slow when you have many fixesgit commit --fixup=<hash> creates a commit with a special message: fixup! original message
Git recognizes the fixup! prefix and knows this commit belongs to the original commit. When you later run git rebase -i --autosquash, Git automatically changes these to fixup actions in the rebase plan.
No need to manually edit the rebase todo list — Git does it for you.
--fixup does not change the original commit — it just marks the NEW commit with a special prefix. The original commit stays untouched until rebase runs.
# Original commit
echo "function login() {}" > auth.js
git add auth.js
git commit -m "feat: add login"
# Hash: abc1234
# Find a typo, create a fixup commit
echo "function login(username) {}" > auth.js
git add auth.js
git commit --fixup=abc1234
# Git creates: "fixup! feat: add login"
# Find another issue, another fixup
echo "// validate" >> auth.js
git add auth.js
git commit --fixup=abc1234
# Git creates: "fixup! feat: add login"
# Check the log
git log --oneline
# def5678 fixup! feat: add login
# ghi9012 fixup! feat: add login
# abc1234 feat: add login
# The "fixup!" prefix tells Git these belong to the original
git rebase -i --autosquash opens the rebase editor with fixup/squash commits PRE-CONFIGURED.
All commits marked with fixup! are automatically set to fixup action. All commits marked with squash! are automatically set to squash action.
They are placed right after their target commit — no manual reordering needed. You just save and close the editor. Git handles the rest.
If you want to review the plan, the editor shows it before execution. You can still make changes if needed.
# History with fixup commits
git log --oneline
# def5678 fixup! feat: add login
# ghi9012 fixup! feat: add login
# abc1234 feat: add login
# Run autosquash
git rebase -i --autosquash HEAD~3
# Editor opens with PRE-CONFIGURED actions:
pick abc1234 feat: add login
fixup def5678 fixup! feat: add login
fixup ghi9012 fixup! feat: add login
# No manual editing needed! Just save and close.
# Result: 3 commits become 1 clean commit
# If you want to change fixup to squash (to edit message):
# Edit in the editor before saving:
pick abc1234 feat: add login
squash def5678 fixup! feat: add login ← changed to squash
fixup ghi9012 fixup! feat: add logingit commit --squash=<hash> is like --fixup, but during rebase it uses squash instead of fixup.
This means: combine with the target commit AND let me edit the combined message.
Use --fixup when: the fix is minor (typo, formatting) and the original message is fine as-is.
Use --squash when: the fix is significant and you want to rewrite the combined commit message.
Both are auto-arranged by --autosquash. The only difference is the rebase action they trigger.
# Original commit
git commit -m "feat: add login"
# Minor fix — use fixup (discard message)
echo "function login(username) {}" > auth.js
git add auth.js
git commit --fixup=HEAD~1
# Will auto-fixup during rebase (no message editing)
# Significant fix — use squash (edit message)
echo "// Added validation and error handling" >> auth.js
git add auth.js
git commit --squash=HEAD~2
# Will auto-squash during rebase (opens editor for message)
# Autosquash rebase
git rebase -i --autosquash HEAD~3
# Editor shows:
pick abc1234 feat: add login
fixup def5678 fixup! feat: add login # auto-set
squash ghi9012 squash! feat: add login # auto-set
# Fixup merges silently, squash opens editor for messageThe professional workflow: commit freely with fixup marks, then autosquash before PR.
Step 1: Make your feature commits normally.
Step 2: When you find issues, commit with --fixup=<original-hash>.
Step 3: Before PR, run git rebase -i --autosquash to clean up.
Step 4: Save and close the editor. All fixups are applied automatically.
Pro tip: Use GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash to skip the editor entirely. This makes the autosquash 100% automatic — no editor opens at all.
# Complete professional workflow
# 1. Feature commits
git commit -m "feat: add authentication"
AUTH_HASH=$(git rev-parse HEAD)
git commit -m "feat: add dashboard"
DASH_HASH=$(git rev-parse HEAD)
# 2. Fix commits (mark with --fixup)
echo "fix" >> auth.js && git add . && git commit --fixup=$AUTH_HASH
echo "fix" >> dashboard.js && git add . && git commit --fixup=$DASH_HASH
echo "fix2" >> auth.js && git add . && git commit --fixup=$AUTH_HASH
# 3. Before PR: autosquash
git rebase -i --autosquash
# Editor shows all fixups pre-configured. Save and close.
# Result: 5 commits become 2 clean commits
# feat: add authentication (includes 2 fixes)
# feat: add dashboard (includes 1 fix)
# 4. Fully automatic (no editor):
GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash
# All fixups applied automatically without opening editor!
# 5. Push
git push --force-with-lease origin feature
git config --global alias.autofixup "rebase -i --autosquash" to make it even faster.Lo kar liya — Key Points:
- ✅ git commit --fixup=<hash> creates a commit marked "fixup! original message" that autosquash will auto-merge
- ✅ git commit --squash=<hash> creates a commit marked "squash! original message" that autosquash will merge with message editing
- ✅ git rebase -i --autosquash automatically arranges fixup/squash commits next to their targets
- ✅ Use --fixup for minor fixes (typos, formatting) where the original message is fine
- ✅ Use --squash for significant fixes where you want to rewrite the combined commit message
- ✅ GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash skips the editor entirely for 100% automation
- ✅ The workflow: commit freely with --fixup marks, then autosquash before PR for clean history
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login