Squashing is a process in which we squeeze multiple commits into one pretending it is only a single commit.
Basically squashing commits means we are rewriting the history of commits to make them look like single commit.
Whenever sending pull requests we need to send it as a single commit.
- If pull request is sent with squashed commits it makes easier for maintainer to check what changes will be brought by the pull-request.
- Another benefit of single commit is if after merging new code, things don't go as planned then instead of going through a lot of commits and finding where things went wrong we can just revert a single commit and our code will start working as it was working earlier.
NOTE: if you are a new git user and not much familiar with "vim editor" I would recommend you to look here "Vim Guide" or if you are using git on Linux you can switch to "nano" which is easy to use.
To switch to nano run following command on your terminal(Linux only).
$ git config --global core.editor "nano"
to save any file in nano
Ctr + o
to exit nano
Ctr + x
Now first, to squash we need to run following command which will allow us to edit the history.
$ git rebase -i HEAD~3
Here -i
allows us to interact with history and not only seeing it.
After HEAD~
you can specify any number and it will display those many last commits. If there are n
commits then you can see only n-1
commits using HEAD~
. To see all the commits you can specify --root
instead of HEAD~
.
The output of the above command will be like this
pick eead26c commit 1
pick 5099af5 commit 2
pick ac6f1b9 commit 3
# Rebase 6166ab6..ac6f1b9 onto 6166ab6 (3 commands)
#
# 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
Here commit 3
is the newest commit and commit 1
is the oldest commit.
We can always only squash newer commits into older commits.
here we will squash commit 2 and 3 into commit 1. To do so we need to change pick
into s
in the line of commit 2 and 3. Save this file After doing following changes this file will look like following.
pick eead26c commit 1
s 5099af5 commit 2
s ac6f1b9 commit 3
# Rebase 6166ab6..ac6f1b9 onto 6166ab6 (3 commands)
#
# 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
Now to anytime after squashing if we want to push this changes into our origin/remote repository we need to push forcefully as we have rewritten the history. To forcefully push use the following command:
$ git push -f
NOTE: Any time if you wish to see the list of commits you can you use:
$ git log
This will list all the commits