How do I squash my last N commits together?

Learn how do i squash my last n commits together? with practical examples, diagrams, and best practices. Covers git, rebase, squash development techniques with visual explanations.

Squashing Your Last N Commits in Git

Hero image for How do I squash my last N commits together?

Learn how to combine your recent Git commits into a single, cleaner commit using interactive rebase, improving your project's history.

Maintaining a clean and understandable Git history is crucial for collaboration and project management. Often, during development, you might make several small, incremental commits that, while useful at the moment, clutter your commit log. Squashing these commits allows you to combine them into a single, more meaningful commit, making your history easier to read and revert if necessary. This article will guide you through the process of squashing your last N commits using Git's powerful interactive rebase feature.

Understanding Git Rebase Interactive

Git rebase interactive (git rebase -i) is a powerful tool that allows you to rewrite your commit history. It presents a list of commits in a text editor, giving you options to modify them. When squashing, you'll instruct Git to combine multiple commits into one. This process is particularly useful for cleaning up feature branches before merging them into a main branch, or for tidying up your local work before pushing to a remote repository.

flowchart TD
    A[Start with multiple commits] --> B{git rebase -i HEAD~N}
    B --> C[Editor opens with commit list]
    C --> D{Mark commits for 'squash' or 'fixup'}
    D --> E[Save and close editor]
    E --> F{Git combines commits}
    F --> G[Editor opens for new commit message]
    G --> H[Write new commit message]
    H --> I[Save and close editor]
    I --> J[Cleaned commit history]

Workflow for squashing commits using git rebase interactive.

How to Squash Your Last N Commits

The core command for squashing commits is git rebase -i HEAD~N, where N is the number of commits you want to go back from your current HEAD. This command will open your default text editor (e.g., Vim, Nano) with a list of the last N commits, ordered from oldest to newest.

1. Determine the number of commits to squash

First, identify how many commits you want to squash. You can use git log --oneline to view your recent commit history and count them. For example, if you want to squash the last 3 commits, N will be 3.

2. Initiate the interactive rebase

Open your terminal and run the command git rebase -i HEAD~N, replacing N with the actual number of commits. For instance, to squash the last 3 commits, you'd type git rebase -i HEAD~3.

3. Edit the rebase instruction file

Your text editor will open, showing a list of commits. The oldest commit will be at the top. By default, each commit will have pick next to it. To squash, you need to change pick to squash (or s) for all commits you want to combine into the previous one. Keep the very first commit as pick as this will be the base for the squashed commit. If you want to combine commits but discard their commit messages, use fixup (or f) instead of squash.

4. Save and close the editor

After making your changes, save the file and close the editor. Git will then start the rebase process.

5. Edit the new commit message

Git will open another editor window, combining the commit messages of all the commits you chose to squash. This is your chance to write a new, concise, and descriptive commit message for the single, squashed commit. Delete the individual messages and write a new one that accurately reflects the combined changes.

6. Finalize the rebase

Save and close the commit message editor. Git will complete the rebase, and your last N commits will now be replaced by a single, squashed commit in your history.

# View your recent commit history
git log --oneline

# Example: Squash the last 3 commits
git rebase -i HEAD~3

# Inside the editor, you'll see something like:
# pick 0a1b2c3 Commit message 1 (oldest)
# pick d4e5f67 Commit message 2
# pick 8g9h0i1 Commit message 3 (newest)

# Change it to:
# pick 0a1b2c3 Commit message 1
# squash d4e5f67 Commit message 2
# squash 8g9h0i1 Commit message 3

# After saving, a new editor opens for the combined commit message:
# # This is a combination of 3 commits.
# # The first commit's message is:
# Commit message 1
#
# # The second commit's message is:
# Commit message 2
#
# # The third commit's message is:
# Commit message 3

# Replace with your new, single commit message:
# Feature: Implemented user authentication and basic profile management

Example of git rebase -i usage for squashing commits.

Force Pushing After Squashing

If you have already pushed the commits you squashed to a remote repository, you will need to force push your changes. This is because you have rewritten history, and your local branch's history no longer matches the remote's. Use git push --force-with-lease as it's a safer alternative to git push --force.

# After squashing, if you need to update a remote branch
git push origin <your-branch-name> --force-with-lease

Safely force pushing after a rebase.