Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

@davoscollective

This comment has been minimized.

Copy link

davoscollective commented Sep 26, 2017

git checkout master && git fetch && git pull

git pull is a synonym for git fetch && git merge so your version will git fetch twice, although the second time it likely won't fetch anything, so it probably doesn't matter.

git merge feature_branch
I think you are better to

  • checkout the feature_branch
  • merge master into it
  • squash your commits on the feature_branch
  • push your feature_branch to the remote (origin or other)
  • create a pull request from the remote feature_branch to the remote master (origin/master).
  • Someone else reviews & merges your (squashed) commit to origin/master.

The reason I say that is because if you've merged your feature_branch to your local master, how do you then push it to origin master with an opportunity for someone else to review & merge your commit? I don't think you can create a pull request from your local to a remote, only push directly,
Although, workflows in git differ, so this might work for you if no-one is reviewing the code and you are happy to just push direct to origin/master. If that's the case, creating branches is more of a convenience for working on multiple discrete changes and being able to switch between them cleanly.

@singhai0

This comment has been minimized.

Copy link

singhai0 commented Oct 11, 2017

👍

@lehone-hp

This comment has been minimized.

Copy link

lehone-hp commented Nov 1, 2017

cool

@patik

This comment has been minimized.

Copy link
Owner Author

patik commented Nov 3, 2017

@davoscollective Thanks for the feedback. I removed the extraneous git fetch.

As for the second part, you are correct that it removes the opportunity for a pull request and probably doesn't work for many teams' workflows. I do have a note/warning in the text about this, however I've made it bolder so hopefully it saves some people a headache.

@AlexCoderBit

This comment has been minimized.

Copy link

AlexCoderBit commented Dec 24, 2017

Very useful )) Thanks.

@johankritzinger

This comment has been minimized.

Copy link

johankritzinger commented Feb 7, 2018

Ta, very useful. I like the first one, and useful even without pushing to master:

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.

At this point, create the branch you're going to create a pull request for:

git checkout -b merging_branch

git add . --all
git commit

git push --set-upstream origin merging_branch

Then create a pull request etc.

@AnrDaemon

This comment has been minimized.

Copy link

AnrDaemon commented Feb 11, 2018

Pro tip: do NOT squash file renames together with file edits. You will end up with lost ancestry history.

@seandockery

This comment has been minimized.

Copy link

seandockery commented Mar 22, 2018

Good article.

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

I am guessing that it is assumed, but you should probably add an explicit "git add" between these statements. Changing -m to -am may not be sufficient if there are new files that were previously un-versioned.

@kkannan-carecloud

This comment has been minimized.

Copy link

kkannan-carecloud commented May 26, 2018

Is it still possible to squash all commits in the remote branch if I have already pushed multiple commits to it ?

@tombusby

This comment has been minimized.

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

This comment has been minimized.

Copy link

IanKemp commented Jun 19, 2018

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

@nigelnindo

This comment has been minimized.

Copy link

nigelnindo commented Jul 6, 2018

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

This comment has been minimized.

Copy link

Qubad786 commented Aug 10, 2018

I usually do squashing while interactive rebase.

git rebase -i origin/master your-branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.