Skip to content

Instantly share code, notes, and snippets.

@patik
Last active October 17, 2023 02:19
Show Gist options
  • Save patik/b8a9dc5cd356f9f6f980 to your computer and use it in GitHub Desktop.
Save patik/b8a9dc5cd356f9f6f980 to your computer and use it in GitHub Desktop.
How to squash commits in git

Squashing Git Commits

The easy and flexible way

This method avoids merge conflicts if you have periodically pulled master into your branch. It also gives you the opportunity to squash into more than 1 commit, or to re-arrange your code into completely different commits (e.g. if you ended up working on three different features but the commits were not consecutive).

Note: You cannot use this method if you intend to open a pull request to merge your feature branch. This method requires committing directly to master.

Switch to the master branch and make sure you are up to date:

git checkout master && git pull

Merge your feature branch into the master branch locally:

git merge feature_branch

Reset the local master branch to origin's state:

git reset origin/master

Now all of your changes are considered as unstaged changed. You can stage and commit them into one or more commits.

git add . --all
git commit

(Source)

The hard(er) and less flexible way

This method only allows you to squash the last X consecutive commits into a single commit. Also, if you have merged master into your branch along the way, you will have to manually merge your new (squashed) commit into master and resolve the merge conflicts.

Use this method if you have not merged master into your branch, you plan to combine all commits into one, and you only changed one feature of the project; or, regardless of those conditions, you must use this method if you intend to open a pull request to merge your code.

Combining the commits

To squash the last 3 commits into one:

git reset --soft HEAD~3
git commit -m "New message for the combined commit"

Pushing the squashed commit

If the commits have been pushed to the remote:

git push origin +name-of-branch

The plus sign forces the remote branch to accept your rewritten history, otherwise you will end up with divergent branches

If the commits have NOT yet been pushed to the remote:

git push origin name-of-branch

In other words, just a normal push like any other


Main source: http://stackoverflow.com/a/5201642/348995
Source for info about when commits where already pushed: http://stackoverflow.com/a/5668050/348995

@tombusby
Copy link

tombusby commented Jun 1, 2018

@kkannan-carecloud, yes, you'll have to do a "git push -f" but be aware that this will cause problems for people that have already pulled that branch.

@IanKemp
Copy link

IanKemp commented Jun 19, 2018

Why would you use the first option over git merge --squash?

@nigelnindo
Copy link

I used to use the second option, but nowadays a much easier way to squash commits I use (for me, at least) is git rebase HEAD~[x number of commits] -i

@Qubad786
Copy link

I usually do squashing while interactive rebase.

git rebase -i origin/master your-branch

@LeslieGerman
Copy link

Your 2nd solution was the only one I could find on the internet, which shows how to do NON-interactive squash on a single branch (not merging).

I had to squash 134 commits, so interactive squash was not attractive for me... 😋

@SehrishHussain
Copy link

can I squash commits I made on separate branches?

@patik
Copy link
Author

patik commented Apr 9, 2021

can I squash commits I made on separate branches?

Do you mean that you have commits on branch A that you want to squash with commits on branch B? I don't think so, at least not with one command. Probably you can merge one branch into the other one first, then squash them.

@ashim-wmg
Copy link

git push origin +name-of-branch

in the + synonymous with force ?

@patik
Copy link
Author

patik commented Nov 7, 2021

in the + synonymous with force ?

According to the docs, it seems to be the same

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment