Skip to content

Git Squash Commits Guide

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Git Squash Commits Guide. We cover key concepts, practical examples, and best practices.

A messy commit history with "fix typo", "oops", "wip" commits makes code review difficult and pollutes the git log. Squashing combines multiple commits into one, creating a clean, meaningful history before pushing or merging.

The Problem

git log --oneline

Shows:

a1b2c3 Fix typo
d4e5f6 Add tests
g7h8i9 WIP
j0k1l2 Implement login feature
m3n4o5 Initial commit

Wrong Approach

# WRONG — resetting and losing all commit messages
git reset --soft HEAD~4
git commit -m "lost all individual commit messages"

Right Approach

git rebase -i HEAD~4

In the editor, change pick to squash:

pick m3n4o5 Initial commit
pick j0k1l2 Implement login feature
squash g7h8i9 WIP
squash d4e5f6 Add tests
squash a1b2c3 Fix typo

Save and exit. Then write the final commit message.

Expected output:

[detached HEAD z9y8x7] Implement login feature with tests
 5 files changed, 120 insertions(+)
Successfully rebased and updated refs/heads/main.

Step-by-Step Guide

Step 1: Identify commits to squash

git log --oneline

Step 2: Start interactive rebase

git rebase -i HEAD~4

Step 3: Mark commits as squash

In the editor, change pick to squash (or s) for all commits you want to combine into the commit above them.

Step 4: Write the squashed commit message

Git opens an editor with all commit messages combined. Write a clear, descriptive message and save.

Step 5: Verify the result

git log --oneline -5

Step 6: Force push if the branch was shared

git push --force-with-lease origin feature-branch

Prevention Tips

  • Squash commits before merging feature branches into main
  • Use git commit --fixup and git rebase -i --autosquash for automatic squashing
  • Keep commits atomic — one logical change per commit
  • Write meaningful commit messages from the start
  • Squash before creating a pull request, not after

Common Mistakes with squash commits

  1. Using head and tail instead of pattern matching, causing runtime errors on empty lists
  2. Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks
  3. Using return to exit a function early instead of wrapping a pure value in the monad

These mistakes appear frequently in real-world GIT code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### What is the difference between squash and fixup in rebase?

squash combines the commit into the previous one and prompts you to merge the commit messages. fixup combines the commit but discards its message, keeping only the previous commit's message. Use fixup for trivial fixes like removing debug prints.

How many commits should I squash?

Squash to one commit per logical feature or bug fix. A good rule is one commit per pull request. The commit message should describe the entire change. Reserve multiple commits for large features where each commit is independently reviewable.

Can I squash commits after pushing?

Yes, but you need git push --force-with-lease because squashing rewrites history. Only squash pushed commits if you are working alone on the branch or have coordinated with your team. Never squash commits on shared branches like main.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro