Git Squash

1 min

Table of contents

  1. What Is Squash?
  2. Why Squash?
  3. Interactive Squash
  4. Immediate Practice
  5. Use Cases

1. What Is Squash?

Git squash = Combine several commits into ONE SINGLE commit.

Analogy: You have 5 drafts of an email → you combine them into 1 clean final email.

Example:

BEFORE squash:
- "fix typo"
- "add feature"
- "fix bug"
- "another fix"

AFTER squash:
- "Add complete login feature"

Back to table of contents

2. Why Squash?

Problem: Dirty history

git log --oneline
abc123 oops fix typo
def456 forgot semicolon
ghi789 actually implement feature
jkl012 fix indent
mno345 real commit message

Solution: Squash!

git log --oneline
xyz999 Implement user authentication system

Benefits:

  • Clean, readable history
  • Logical commits per feature
  • Easier to revert a complete feature

Back to table of contents

3. Interactive Squash

The magic command:

bash
git rebase -i HEAD~4    # Squash the last 4 commits

Interface that opens:

pick abc123 oops fix typo
pick def456 forgot semicolon
pick ghi789 actually implement feature
pick jkl012 fix indent

Change to:

pick ghi789 actually implement feature
squash abc123 oops fix typo
squash def456 forgot semicolon
squash jkl012 fix indent

Result: 4 commits → 1 clean commit!

Back to table of contents

4. Immediate Practice

bash
mkdir demo-squash && cd demo-squash
git init

# Create several "dirty" commits
echo "print('v1')" > app.py && git add . && git commit -m "start feature"
echo "print('v1.1')" > app.py && git add . && git commit -m "oops fix"
echo "print('v1.2')" > app.py && git add . && git commit -m "another fix"
echo "print('v2 done')" > app.py && git add . && git commit -m "feature complete"

# Dirty history
git log --oneline

# Interactive squash
git rebase -i HEAD~4

# In the editor: keep the first "pick", change the others to "squash"
# Save and close

# Write the final commit message
# Result: 1 clean commit!
git log --oneline

Back to table of contents

5. Use Cases

Typical situations:

  1. Feature branch before merge:

    bash
    git checkout feature-login
    # ... 15 dev commits with typos/fixes
    git rebase -i HEAD~15    # Squash into 2-3 logical commits
    git checkout main && git merge feature-login
  2. Clean up before push:

    bash
    # Local draft development
    git rebase -i HEAD~8     # Clean up before sharing
    git push origin feature-branch
  3. Fix the public history (careful!):

    bash
    # Only if nobody has retrieved your commits yet
    git rebase -i HEAD~5
    git push --force-with-lease    # Safer than --force

Squash = Your vacuum cleaner for cleaning up history!

Back to table of contents