Back
GitoryxGitoryx

How to Squash Commits in Git

Squashing combines several commits into one clean commit. This tutorial shows three methods (soft reset, interactive rebase, merge --squash), how to push safely with force-with-lease, and what to avoid on shared branches.

Intermediate8 min readUpdated

On this page

What does squashing commits mean?

Squashing combines several commits into a single one. The quickest way is git reset --soft HEAD~N followed by a new commit, or git rebase -i HEAD~N and marking the later commits as squash. Rewrites history, so only do it on commits you have not shared.

The short version

  1. 1Count the commits to combine: git log --oneline
  2. 2Soft reset: git reset --soft HEAD~3
  3. 3Create one commit: git commit -m "Message"
  4. 4Or use git rebase -i HEAD~3 and mark later commits squash
  5. 5Push safely: git push --force-with-lease

Why it matters

Your branch has fifteen commits named 'wip', 'fix typo', and 'try again', and the pull request is about to be reviewed. You want one or two clean commits that tell the story.

Squashing combines several commits into one. It keeps the main history readable, makes reverts simple, and lets reviewers see intent instead of your trial and error.

Where it usually goes wrong

  • Squashing commits that were already pushed and shared, then breaking teammates' branches
  • Marking every commit as squash in interactive rebase, including the first one
  • Losing the commit message while squashing
  • Using git reset --hard instead of --soft and discarding work

Squashing commits, step by step

  1. Step 1: Check which commits to squash

    List the recent commits and count how many belong together. They must be consecutive.

    Terminal
    git log --oneline -8# 9d1c3aa fix typo# 4be7f12 wip# a20c8e3 add search box# 77f0b4d previous work (keep)

    Tip: Make a safety branch first: git branch backup/search. If something goes wrong, you can return to it.

  2. Step 2: Fastest method: soft reset and recommit

    --soft moves the branch back but keeps all changes staged. One new commit then replaces the whole group.

    Terminal
    # Squash the last 3 commitsgit reset --soft HEAD~3git commit -m "Add search box"

    Careful: Use --soft, never --hard: --hard throws the changes away.

  3. Step 3: Flexible method: interactive rebase

    Open the last N commits in an editor. Keep pick on the first commit and change the others to squash (keep messages to edit) or fixup (discard messages).

    Terminal
    git rebase -i HEAD~3# In the editor:pick a20c8e3 add search boxsquash 4be7f12 wipfixup 9d1c3aa fix typo

    Tip: The oldest commit is at the top. Never change the first line to squash: there is nothing before it to combine with.

  4. Step 4: Squash everything on a feature branch

    To collapse the whole branch into one commit, reset to where it diverged from main.

    Terminal
    git reset --soft $(git merge-base main HEAD)git commit -m "Add search feature"
    In Gitoryx: Select consecutive commits on the graph and squash them into oneHow it works
  5. Step 5: Squash while merging

    git merge --squash applies a branch's changes as staged edits without creating a merge commit, so you commit them as one.

    Terminal
    git switch maingit merge --squash feature/searchgit commit -m "Add search feature"

    Tip: GitHub and GitLab offer the same as a 'Squash and merge' button on pull requests.

  6. Step 6: Push the rewritten branch

    History changed, so a normal push is rejected. Use --force-with-lease, which refuses if someone else pushed in the meantime.

    Terminal
    git push --force-with-lease

    Careful: Only force-push branches that nobody else is working on. Never force-push main.

Mistakes to avoid with squashing commits

Squashing shared history
Rewriting commits others already pulled forces them to reconcile two versions of the same work.
Fix: Squash only your own unpushed commits, or a feature branch you own. Use git revert for shared history.
Using plain --force
git push --force overwrites the remote even if a teammate pushed new commits in the meantime.
Fix: Use git push --force-with-lease instead.
Squashing non-consecutive commits
Squash combines neighbours. Commits separated by unrelated ones need reordering first.
Fix: Reorder lines in git rebase -i, or use git commit --fixup and git rebase -i --autosquash.

Squashing commits in Gitoryx

Gitoryx lets you select consecutive commits in the graph and squash them into one with a single action, with a preview of the final message.

  • Select consecutive commits on the graph and squash them into one
  • Edit the combined commit message before confirming
  • See the history before and after, with the backup visible in the reflog
  • Force-push safely with lease protection from the push dialog

Free plan · no account required · macOS, Windows and Linux

Squashing commits: frequently asked questions

How do I squash the last 2 commits?
Run git reset --soft HEAD~2 then git commit -m "your message". Or use git rebase -i HEAD~2 and change the second commit to squash.
What is the difference between squash and fixup?
Both merge a commit into the previous one. squash lets you edit the combined message; fixup discards the squashed commit's message.
Can I undo a squash?
Yes, as long as you act soon. Find the old tip with git reflog and run git reset --hard <sha>.
Should I squash before merging a pull request?
It is a good idea when commits are noisy. Many teams use 'Squash and merge' to keep a linear main history with one commit per pull request.
Does squashing lose my changes?
No. The final content is identical; only the number of commits and their messages change.
All Git tutorials →
Gitoryx

Stop fighting Git. Start shipping.

Download the fast, native Git client that developers actually enjoy using.

v1.1.0 · macOS 12+ (Apple Silicon or Intel) · Windows 10+ · Linux x86_64