How to Combine Multiple Git Commits into One

An interactive rebase mode allows you to combine your commits into even a single commit. While working in Git, developers often make temporary commits that may have not appropriate commit messages. Before merging those commits to the master, it is necessary to combine them into a single commit with clear and comprehensive commit message. It is essential to do for having a clear commit history.

Watch a course Git & GitHub - The Practical Guide

Steps to merging multiple commits

Let's see how you can change your dirty history and make it clean by taking some easy steps. The history will have a messy look like this:

easy steps for cleaning history

This kind of history full of meaningless commits makes it difficult for your team to see your finished product. A quick solution is combining multiple commits into one. To do so, you should follow the steps below.

Running git rebase in interactive mode

Suppose that you want to merge the last 3 commits into a single commit. To do that, you should run git rebase in interactive mode (-i) providing the last commit to set the ones that come after it. Here, HEAD is the alias of the very last commit.

git rebase -i HEAD~3
Note that HEAD~3 means three commits prior to the HEAD. You can select the appropriate commit by its hash.
If you have merge in you commits, it requires different actions.

Typing "squash"

After the first step, the editor window will show up offering you to input the command for each commit. All you need to do is replacing pick with squash, starting from the second line. Then, save the file.

 Type Squash

Choosing between commit messages

One more editor window will show up to change the resulting commit message. Here, you can find all your commit messages and change them according to your exact needs.

Choose Between Commit Messages

Pushing changes

You should run git push to add a new commit to the remote origin. If you have already pushed your commits, then you should force push them using the git push command with --force flag (suppose, the name of remote is origin, which is by default):

git push --force origin HEAD
--force overwrites the remote branch on the basis of your local branch. It destroys all the pushed changes made by other developers. It refers to the changes that you don't have in your local branch.

Here is an alternative and safer way to push combined commits:

git push --force-with-lease origin HEAD
--force-with-lease is considered a safer option that will not overwrite the work done on the remote branch in case more commits were attached to it (for instance, by another developer). Moreover, it helps you to avoid overwriting another developer's work by force pushing.

Squashing

When you work on some new feature you make several intermittent commits in the history. It is more convenient to have all of the commits combined into one.

There is no git squash command in Git. Squashing pull request means to combine all the commits in that request into one to make it easier to read and clean the history of the main branch. To achieve that you should to use interactive mode of the git rebase command described above.

The squashing process is dangerous if your branch has already been published in the remote repository. Thus, it is best to squash on the local branch before pushing. If you have already pushed it, then, for creating pull request you should force the changes on the remote branch after squashing operation as the histories of local and remote branches are different.