---
title: "Squash Your Commits"
date: 2020-11-08T18:05:29.000Z
author: Z.SHINCHVEN
tags: [git]
canonical: https://atlassc.net/2020/11/09/squash-your-commits
---
## Do You Commit A Lot?

When I work on a project, I used to commit every little progress, so that I can feel safe to move forward.

But it makes my commit history a mess.

However, git provides a few ways to manage and squash commits, so that I can organize my commit history after I finish a feature.

Let's take a look at how to squash commits.

> ### 🚨 Before You Start
> Make sure you have committed all your changes, and you are on the branch you want to squash commits.

## Squash A Few Latest Commits by Using `Git Reset`

> [git reset](https://git-scm.com/docs/git-reset#Documentation/git-reset.txt) - 
> Reset current HEAD to the specified state

> [git reset --soft](https://git-scm.com/docs/git-reset#Documentation/git-reset.txt---soft) - 
> Does not touch the index file or the working tree at all (but resets the head to <commit>, just like all modes do). This leaves all your changed files "Changes to be committed", as git status would put it.

It is a simple and none-interactive way to squash `a few latest contiguous commits`.

```bash
# Reset a number of current commits, and keep the changes
git reset --soft HEAD~<NUMBER_OF_COMMITS>
# Commit the changes to make a squash
git commit -m 'new commit message'
```

### If Anything Goes Wrong

Don't freak out.

You can use `git reset 'HEAD@{1}'` reset your reset, according to this [answer](https://stackoverflow.com/a/2531803/2108080) on stackoverflow. `'HEAD@{1}'` is the state of `HEAD` 1 moves ago, you can find it by using `git reflog`.

> [git reflog](https://git-scm.com/docs/git-reflog) -
> Manage reflog information 

## Squash Commits Interactively by Using `Git Rebase`

> [git rebase](https://git-scm.com/docs/git-rebase) -
> Reapply commits on top of another base tip

This is an interactive way to squash `picked commits`.

To do so, please run the following command:

```bash
# rebase a number of commits from current commit
git rebase -i HEAD~<number of commits>
# For example, if you want to squash the last 3 commits, run:
git rebase -i HEAD~3
```

Now you will see an editor with a list of commits you can pick to squash.

```text
pick 1a2b3c4 commit message 1
pick 4d5e6f7 commit message 2
pick 7g8h9i0 commit message 3
```

To squash picked commits, you simply need to replace the word `pick` at the beginning of each line to `squash` or `s`, except the first line.

```diff
pick 1a2b3c4 commit message 1
- pick 4d5e6f7 commit message 2
+ sqush 4d5e6f7 commit message 2
- pick 7g8h9i0 commit message 3
+ s 7g8h9i0 commit message 3
```

Then save and exit git editor, you will see another new editor to commit the squash changes.

If you squashed a number of none-contiguous commits, you will be asked a few times to commit the squash changes.

### If Anything Goes Wrong

Don't panic, you can always run the following command to fix or reset state:

- `git rebase --abort` to abort the rebase
- `git rebase --continue` to continue the rebase.
- `git rebase --skip` to skip the current commit.
- `git rebase --edit-todo` to edit the todo list.
- `git rebase --show-current-patch` to show the current patch.
