Git Squash Commits
We will learn about Git squashing in this tutorial. The basic idea is to merge multiple consecutive commits into one.
The main purpose is to compress many commits into a few related commits. Thus, doing so will make the git history look concise and clear.
Another way to look at it is that we make multiple commits for a certain task. After a while, when we reach a satisfactory state, many commit messages clutter the git history.
At this point, we may want to merge the different commits into one so that the git history looks clean and best reflects what has been accomplished.
Another use case is squashing when merging branches. Usually, we create a feature branch from the main branch for some feature development.
Once the feature is completed, we merge the feature branch into the master branch. Here, we may also want to squash the various commit messages done in the feature branch into one when merging into the master branch.
Note that there is no git squash
command.
There are two ways to implement Git compression:
-
git rebase -i
As an interactive tool for squashing commits -
git merge -squash
-squash
Use the option when merging
git rebase
Squash Git commits
using the interactive tool
Consider the following git log excerpt, which shows HEAD
the last four commits that we are interested in squashing.
25c38c4 remove .class files
da66e6a Delete version.ini
f4e3f09 Delete .log
b0e6655 Delete .lock
da66e6a github git notes
We can see the first four commit messages in the log, representing the actions of deleting different unrelated files. Now, we will merge these four commits into one.
Following is the syntax of the command to squash the last X commits using the interactive rebase tool.
git rebase -i HEAD~[X]
So, to squash the four commits, we would do the following.
$ git rebase -i HEAD~4
After issuing this command, Git will invoke the default editor with the details of the commit to squash as shown below.
pick b0e6655 Delete .lock
pick f4e3f09 Delete .log
pick da66e6a Delete version.ini
pick 25c38c4 remove .class files
# Rebase 652d2fe..25c38c4 onto 652d2fe (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
The editor pick
displays the various commits using the command. It also displays information about the available commands. We will use the squash
(or s
) command.
As shown below, we will pick
keep the first commit using the -p (for squash) command and change the remaining three commits from pick
-p s
(for squash) command.
pick b0e6655 Delete .lock
s f4e3f09 Delete .log
s da66e6a Delete version.ini
s 25c38c4 remove .class files
# Rebase 652d2fe..25c38c4 onto 652d2fe (4 command(s))
#
...
Commits marked with squash
( or s
) will be merged into the master commit i.e. pick
the one marked with .
Now, we will save the changes in the editor and exit. After this, rebase -i
the tool will open another editor to enter the commit message, as shown below:
# This is a combination of 4 commits. The first commit's message is:
Delete .lock
# This is the 2nd commit message:
Delete .log
# This is the 3rd commit message:
Delete version.ini
# This is the 4th commit message:
remove .class files
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Sun Jan 3 16:39:23 2021 +0530
#
# interactive rebase in progress; onto 652d2fe
# Last commands done (4 commands done):
# pick b0e6655 Delete .lock
# s f4e3f09 Delete .log
# s da66e6a Delete version.ini
# s 25c38c4 remove .class files
# No commands remaining.
# You are currently editing a commit while rebasing branch 'master' on '652d2fe'.
#
# Changes to be committed:
# new file: github-git-notes.txt
#
Now we will add our new commit message on top of the first commit message.
Deleted irrelevant files
# This is a combination of 4 commits. The first commit's message is:
Delete .lock
# This is the 2nd commit message:
Delete .log
...
After saving and exiting the editor, rebase -i
the tool will print the following message.
HEAD~2
Rebasing (2/2)
[detached HEAD caab6e8] Deleted irrelevant files
Date: Sun Jan 3 16:39:23 2021 +0530
1 file changed, 54 insertions(+)
create mode 100644 github-git-notes.txt
Successfully rebased and updated refs/heads/master.
Now, we will check out git log
and see squashed
the commit (that is) a single commit message instead of four commit messages.
$ git log --oneline
25c38c4 Deleted irrelevant files
da66e6a github git notes
...
Using git merge -squash
Squashed Git Commits
Following is the command syntax to merge a branch with the current branch (usually main
) and squash the source branch's commits.
git merge --squash <source_branch_name_to_squash>
We will now merge the feature branch i.e. squash it feature1
with main
the branch.
First, we'll switch to master
the branch.
$ git checkout main
Switched to branch 'main'
We will then squash
execute using the option git merge
as shown below.
$ git merge --squash feature1
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested
When we --squash
execute merge with the merge option merge
, Git does not create a merge commit in the target branch as it does in a normal merge. Instead, Git takes all the changes in the source branch and feature1
puts them as local changes master
in the target branch i.e. the working copy of merge.
See below.
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: config.ini
Here, the files are changed in the branch config.ini
.feature1
Now, all that remains is to commit the changes to main
the branch as shown below.
$ git commit -am 'Merged and squashed the feature1 branch changes'
[main 573b923] Squashed and merged the feature1 branch
1 file changed, 4 insertions(+)
So, we have now feature1
merged the changes from the branch into main
the branch, while squashing feature1
the commit messages from the branch. We now main
have only one commit message in the branch.
For reprinting, please send an email to 1244347461@qq.com for approval. After obtaining the author's consent, kindly include the source as a link.
Related Articles
Close the Git commit editor on Windows
Publish Date:2025/03/31 Views:62 Category:Git
-
In this article, we will discuss how to exit the Git commit editor. This can be a little tricky, especially if you are new to Git bash . Let's see how to exit the editor on Windows. Close the Git commit editor on Windows We will look at a t
Merge remote branches into local branches in Git
Publish Date:2025/03/31 Views:134 Category:Git
-
This tutorial will merge a remote git branch into a local branch by cloning the remote repository and updating the changes locally. Merge remote branches into local branches in Git by cloning the remote repository and updating the changes l
Changing drives in Git Bash
Publish Date:2025/03/30 Views:57 Category:Git
-
This short article will discuss how we can use Git Bash to have a Unix-style command line environment in Windows operating system and run multiple commands in this terminal. Git Bash Git is a collection of command-line utilities created to
Adding a remote branch in Git
Publish Date:2025/03/30 Views:142 Category:Git
-
Git does not allow its developers to create new branches on remote repositories. But instead, we can push an already existing local branch, and after doing so, we can bring it to the remote repository using some Git commands. In every versi
Synchronize your local repository with a remote repository in Git
Publish Date:2025/03/30 Views:92 Category:Git
-
This article outlines the process of syncing your local repository with a remote repository. We will also see how to sync a GitHub branch with a remote repository on the command line. Synchronize your local repository with a remote reposito
Creating a remote repository from a local repository in Git
Publish Date:2025/03/30 Views:106 Category:Git
-
This article discusses the necessary steps to create a remote repository based on a local repository. This is ideal when you have a local repository that needs to be available on a remote or SSH-enabled server. Creating a remote repository
Removing the upstream repository in Git
Publish Date:2025/03/30 Views:177 Category:Git
-
This article will teach you how to delete an upstream repository in Git. We may sometimes need to delete or change the remote repository that we use with our local repository. To do this, we can use the Git command git remote . Removing the
Git remote add SSH
Publish Date:2025/03/30 Views:53 Category:Git
-
In this day and age, the most widely used version control system is Git, which is operated by most developers within a team structure. This is mainly used to increase code efficiency, no matter how big or critical the project is. In this se
Differences between Git Reset, Revert and Checkout commands
Publish Date:2025/03/30 Views:186 Category:Git
-
This article discusses the differences between the git reset , , git revert and git checkout commands. These are some of the most useful Git utilities that allow us to undo certain changes in our repository. It’s easy to get confused with