# How to Squash Commits in Git

Ever struggled to understand a messy Git history filled with tiny, incremental commits? Squashing commits is your solution for a cleaner, more navigable project timeline. This powerful Git technique allows you to combine multiple related commits into a single, meaningful one, significantly improving clarity when reviewing pull requests or tracking down changes.

TLDR:
  1. git rebase -i HEAD~N
  2. picks/f
  3. :wq
  4. git push --force-with-lease

1. Start an Interactive Rebase: git rebase -i HEAD~N or git rebase -i {commit-hash}

The first step is to initiate an interactive rebase. This is a useful Git command that allows you to modify commits in various ways, including squashing them.

Once you run this command, Git will open your default text editor (usually Vim or Nano) with a list of the commits you've selected. Each line will look something like this:

pick f7f3f6d Good commit message
pick 310154e Fix typo
pick a5f4a0d Upd style

These are listed with the oldest commit in your selection at the top and the newest at the bottom.

2. Choose Which Commits to pick and squash

Now, you'll tell Git how to handle each commit in the list. You do this by changing the word pick at the beginning of each line (except usually the first one you want to keep).

Example:

pick f7f3f6d Good commit message
f 310154e Fix typo
f a5f4a0d Upd style

Other useful interactive rebase commands (though not the focus here) include reword (to change the commit message without altering the content), edit (to amend the commit's content), and drop (to delete the commit entirely).

3. Save & Edit Commit Message

Once you've marked your commits with pick and squash (or other commands), save the file and close your editor.

If your default editor is Vim, you do this by typing :wq and pressing Enter. For Nano just press Ctrl+X. For other editors, use their standard save and quit commands.

After you save the rebase instruction file, Git will process the squashing. It will then open another editor window. This time, it's for you to create the commit message for the new, combined (squashed) commit.

Git will typically pre-fill this new message with a concatenation of all the commit messages from the commits you squashed. You should edit this thoroughly to create a single, clear, and concise message that accurately describes the combined changes.

Push Your Changes: git push --force or git push --force-with-lease

Because rebasing (and thus squashing) rewrites commit history, your local branch will now have a different history than its remote counterpart. A regular git git push will be rejected by the remote repository because the histories have diverged.

To update the remote branch with your new, squashed history, you must use a force push:

Best Practices for Force Pushing:

What if something goes wrong during the rebase?

If you make a mistake during the interactive rebase process or change your mind, you can usually abort it and return your branch to its state before you started the rebase by running: git rebase --abort