How to Squash Commits in Git (Combine, Clean History, Before & After Push)

How to Squash Commits in Git (Combine, Clean History, Before & After Push)

What is Git Squash?

Git squash is used to combine multiple commits into a single commit. This helps clean up your commit history, making it easier to read, review, and manage.

For example, instead of having 5 small commits like:

  • fix typo
  • update variable
  • minor change
  • debug logs
  • final fix

👉 You can squash them into one meaningful commit like:

  • add login feature

What does squash commits mean in Git?

Squashing commits means merging multiple commits into one so that the history becomes cleaner and more meaningful.

👉 In simple terms:

Git squash = combine or collapse multiple commits into a single commit

This is especially useful when:

  • You made many small “work-in-progress” commits
  • You want to present a clean history before sharing code
  • You want each commit to represent a complete logical change

Git Squash – Quick Cheat Sheet

DescriptionCommand
Squash last 2 commitsgit rebase -i HEAD~2
Squash last N commitsgit rebase -i HEAD~N
Squash last 3 commitsgit rebase -i HEAD~3
Squash all commits in branchgit rebase -i --root
Squash commits before pushgit rebase -i HEAD~N
Squash commits after pushgit rebase -i HEAD~N + git push -f
Squash commits into oneinteractive rebase (use squash)
Squash specific commitsinteractive rebase (pick/squash manually)
Squash range of commitsgit rebase -i <commit-hash>
Squash commits using mergegit merge --squash <branch>
Combine commits (alternative term)git rebase -i
Collapse commit historygit rebase -i
Abort squash operationgit rebase --abort
Continue after conflictgit rebase --continue
Skip problematic commitgit rebase --skip
Undo squash using refloggit reflog + git reset
Force push squashed commitsgit push -f
Safer force pushgit push --force-with-lease
Verify commit historygit log --oneline
Check current branch stategit status

** Quick Examples**

bash
# Squash last 2 commits
git rebase -i HEAD~2

# Squash last 3 commits
git rebase -i HEAD~3

# Squash all commits into one
git rebase -i --root

# Squash commits using merge
git merge --squash feature-branch

# Undo squash using reflog
git reflog
git reset --hard <commit-id>

Squash Last N Commits

Squash last 2 commits

One of the most common use cases of git squash is combining the last two commits into a single commit using interactive rebase.

bash
git rebase -i HEAD~2

This opens an editor where you can mark one commit as pick and the other as squash, effectively merging them into one. This workflow is part of git rebase explained.

Squash last 3 or multiple commits

To squash more than two commits, increase the range:

bash
git rebase -i HEAD~3

or

bash
git rebase -i HEAD~N

Before squashing, you can inspect commit history using:

bash
git log --oneline

For better understanding of commit history navigation, refer to git head caret vs tilde examples.

Squash commits into one

To combine multiple commits into a single commit:

bash
git rebase -i HEAD~N

During the process:

  • Keep the first commit as pick
  • Mark remaining commits as squash

👉 This approach is commonly used to combine or collapse commits into a clean history, especially before sharing code.


Squash All Commits in a Branch

Combine all commits before push

Before pushing changes, you may want to squash all commits into one clean commit:

bash
git rebase -i --root

This rewrites the entire commit history of the branch into a single commit.

👉 This is useful when working on feature branches created using git branch examples.

Clean commit history for PR

When raising a pull request, it is a best practice to squash commits into a single meaningful change.

Instead of multiple small commits, you present a clean history which is easier to review and maintain. This aligns with best practices discussed in git workflow.

Squash all commits into one (entire branch)

To squash all commits in a branch:

bash
git rebase -i --root

Then mark all commits except the first as squash.

👉 This directly targets use cases like:

  • git squash all commits
  • squash all commits in branch

Squash Commits Before Push

Use interactive rebase safely

The safest way to squash commits is before pushing them to a remote repository.

bash
git rebase -i HEAD~N

Since these commits are still local, you can rewrite history without affecting others.

👉 This is the recommended approach for:

  • git squash commits locally
  • git squash before push

For pushing changes after cleanup, refer to git push examples.

Edit commit message after squash

After squashing, Git will prompt you to edit the final commit message.

You should:

  • Remove unnecessary messages
  • Write a clear and meaningful description

For example:

  • Instead of: “fix”, “update”, “change”
  • Use: “Add user authentication feature”

You can further refine commit messages using git commit amend examples or follow best practices from git commit message.


Squash Commits After Push (Advanced & Risky)

Rewrite pushed commits using rebase

If you have already pushed commits and want to squash them, you can still use interactive rebase:

bash
git rebase -i HEAD~N

However, this rewrites commit history, so it should be used carefully. This approach is part of advanced workflows explained in git rebase.

Force push after squash

After rewriting history, you must force push the changes:

bash
git push -f

A safer alternative is:

bash
git push --force-with-lease

This ensures you don’t accidentally overwrite others’ work. For more details, refer to git push force examples.

When NOT to squash pushed commits

Avoid squashing commits after push when:

  • The branch is shared with other developers
  • Others have already pulled your changes
  • You are working on a production or stable branch

⚠️ In such cases, rewriting history can break collaboration. Instead, consider safer approaches like git revert examples to undo changes without modifying history.


Squash Commits Using Merge

git merge --squash explained

Another way to squash commits is using merge:

bash
git merge --squash <branch>

This combines all commits from the source branch into a single commit before merging. This method is commonly used in pull request workflows explained in git merge examples.

Difference between squash merge and rebase squash

  • git rebase -i → rewrites commit history by combining commits
  • git merge --squash → combines commits during merge without preserving history

👉 To understand when to use each approach, refer to git merge vs rebase.


Squash Specific or Non-Sequential Commits

Squash selected commits

Interactive rebase allows you to squash specific commits by choosing which commits to combine:

bash
git rebase -i <commit-hash>

You can mark selected commits as squash while keeping others unchanged.

Squash commits in middle of history

To squash commits that are not the most recent ones:

bash
git rebase -i <commit-hash>

This lets you rewrite a specific portion of history instead of only the latest commits.

👉 Be cautious when modifying older commits, as it rewrites history.

Squash a range of commits

To squash commits within a specific range:

bash
git rebase -i <start-commit>

This gives full control over which commits to combine.

If something goes wrong during rebase, you can recover using git reflog tutorial and reset to a previous state using git reset examples.


Additional Scenarios

Squash old commits (rewrite history)

Sometimes you may need to squash older commits instead of just the latest ones. This can be done using interactive rebase starting from a specific commit:

bash
git rebase -i <commit-hash>

This allows you to rewrite history and clean up older changes. Since this modifies commit history, it should be used carefully, especially on shared branches.

Squash local vs remote commits

  • Local commits → Safe to squash using rebase
  • Remote commits → Require force push after squash

If commits are already pushed, you must run:

bash
git push -f

or the safer option:

bash
git push --force-with-lease

👉 Rewriting remote history can affect other developers. If unsure, consider safer alternatives like git revert examples.

Combine or collapse commits

Git squash is also commonly referred to as:

  • combining commits
  • collapsing commits
  • cleaning commit history

These terms are often used interchangeably in Git workflows. Understanding this helps when searching for solutions or collaborating with teams.

Squash commits using GUI tools (SourceTree, GitKraken)

If you prefer a graphical interface, many Git tools support squash operations:

  • SourceTree → interactive rebase UI
  • GitKraken → drag-and-drop squash commits

These tools internally use concepts like rebase and merge, similar to git rebase, but provide a visual workflow.


Common Errors and Fixes

cannot squash commits / rebase failed

This usually happens due to:

  • Incorrect commit range
  • Conflicts during rebase
  • Detached HEAD state

Fix:

bash
git rebase --abort
git rebase -i HEAD~N

If you are in a detached HEAD state, refer to git detached head examples.

conflicts during squash

Conflicts can occur when multiple commits modify the same lines.

Fix:

  1. Resolve conflicts manually
  2. Stage the changes
  3. Continue rebase:
bash
git rebase --continue

To understand differences better, refer to git diff examples.

already pushed commits issue

If commits are already pushed, squashing requires rewriting history and force pushing:

bash
git push -f

⚠️ This can overwrite remote history.

A safer alternative is to undo changes using git revert examples instead of rewriting history.

undo squash commit

If something goes wrong after squashing, you can recover using reflog:

bash
git reflog
git reset --hard <commit-id>

This allows you to restore the previous state of your repository. Learn more in git reflog tutorial.


Frequently Asked Questions

1. What is git squash?

Git squash is used to combine multiple commits into a single commit to clean up commit history before sharing or merging code.

2. How do I squash commits in Git?

You can squash commits using git rebase -i HEAD~N and marking commits as squash to combine them into one.

3. Can I squash commits after pushing?

Yes, but it requires rewriting history and force pushing using git push -f, which may affect other developers.

4. How do I squash all commits in a branch?

You can squash all commits using git rebase -i --root and combining them into one commit.

5. How do I undo a squash commit?

You can recover squashed commits using git reflog and restore them with git reset --hard <commit-id>.

Summary

Git squash is a powerful technique to combine multiple commits into a clean and meaningful commit history.

In this guide, you learned how to:

  • Squash recent commits and entire branches
  • Combine commits before and after push
  • Use both rebase and merge-based squash
  • Handle advanced scenarios like partial squash and history rewrite
  • Fix common errors and recover from mistakes

Using git squash effectively helps maintain a clean repository, improves code reviews, and ensures better collaboration in team environments.


Official Documentation

For more details, refer to the official Git documentation:

Steve Alila

Steve Alila

Specializes in web design, WordPress development, and data analysis, with proficiency in Python, JavaScript, and data extraction tools. Additionally, he excels in web API development, AI integration, and data presentation using Matplotlib and Plotly.