How to Squash Git Commits

28/12/2020
Git

How to Squash Commits in Git to Keep Your History Clean

When you are working with Git, it’s a good idea to commit often, so you can always go back to the state of the code if you mess up. However, committing all those mini-changes to the main branch is not always a good idea. It makes the history messy and hard to follow.

Git provides a way to squash a bunch of your commits using the rebase command. Once you have locally made your changes to a particular file or for a particular feature, you can always use the squash method to combine the changes together before you commit to the main branch. This will help other understand your changes better.

Warning: Even though you can pull from external repositories and squash commits together, it’s a bad idea. It can create conflicts and confusion. Avoid changing history that is already public. Only stick to squashing commits that are local to your work.

Let’s work through an example case.

Suppose, we have two files a.py and b.py. Let’s first go through the process of creating the files and making the modifications:

$ mkdir myproject
$ cd myproject/
$ git init
$ echo "print("hello A")" > a.py
$ git add -A && git commit -m "Added a.py"
$ echo "print("hello B")" > b.py
$ git add -A && git commit -m "Added b.py"
$ echo "print("hello BB")" > b.py
$ git add -A && git commit -m "b.py Modification 1"
$ echo "print("hello BBB")" > b.py
$ git add -A && git commit -m "b.py Modification 2"

If we check the history of commits, we will see the following:

$ git log –oneline –graph –decorate
* dfc0295 (HEAD –> master) b.py Modification 2
* ce9e582 b.py Modification 1
* 7a62538 Added b.py
* 952244a Added a.py

After we are done with our work, we decide to put all the changes to the b.py into a single commit for clarity. We count that there are 3 commits on b.py from the HEAD. We issue the following command:

git rebase -i HEAD~3

The -i option tells Git to use the interactive mode.

It should pop up a window on your Git text editor:

pick 7a62538 Added b.py
pick ce9e582 b.py Modification 1
pick dfc0295 b.py Modification 2
 
# Rebase 952244a..dfc0295 onto 952244a (3 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
#
# 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 commits are listed chronologically on the top from the earliest to the most recent. You can choose which commit to “pick” and which commits to squash. For simplicity, we will pick the first commit and squash the rest into it. So we will modify the text like this:

pick 7a62538 Added b.py
squash ce9e582 b.py Modification 1
squash dfc0295 b.py Modification 2
 
# Rebase 952244a..dfc0295 onto 952244a (3 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
#
# 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

As soon as you save and close the text file, another text window should pop up that looks like this:

# This is a combination of 3 commits.
# The first commit’s message is:
Added b.py
 
# This is the 2nd commit message:
 
b.py Modification 1
 
# This is the 3rd commit message:
 
b.py Modification 2
 
# Please enter the commit message for your changes. Lines starting
# with ‘#’ will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Mar 30 21:09:43 2018 -0700
#
# rebase in progress; onto 952244a
# You are currently editing a commit while rebasing branch ‘master’ on ‘952244a’.
#
# Changes to be committed:
#       new file:   b.py
#

Save and close this file too. You should see something like this:

$ git rebase -i HEAD~3
[detached HEAD 0798991] Added b.py
Date: Fri Mar 30 21:09:43 20180700
1 file changed, 1 insertion(+)
create mode 100644 b.py
Successfully rebased and updated refs/heads/master.

If you check the commit history now:

$ git log –oneline –graph –decorate
* 0798991 (HEAD –> master) Added b.py
* 952244a Added a.py

All the commits for b.py have been squashed into one commit. You can verify by looking at the b.py file:

$ cat b.py
print("hello BBB")

It has the content of Modification 2.

Conclusion

The rebase is a powerful command. It can help you keep your history clean. But avoid using it for already public commits as it can cause conflicts and confusion. Only use it for your own local repository.

Further Study:

ONET IDC thành lập vào năm 2012, là công ty chuyên nghiệp tại Việt Nam trong lĩnh vực cung cấp dịch vụ Hosting, VPS, máy chủ vật lý, dịch vụ Firewall Anti DDoS, SSL… Với 10 năm xây dựng và phát triển, ứng dụng nhiều công nghệ hiện đại, ONET IDC đã giúp hàng ngàn khách hàng tin tưởng lựa chọn, mang lại sự ổn định tuyệt đối cho website của khách hàng để thúc đẩy việc kinh doanh đạt được hiệu quả và thành công.
Bài viết liên quan

Install Git on CentOS 7.5

Git is a very popular Version Control System (VCS). It is written by the creator of Linux Kernel, Linus Torvalds. It is...
28/12/2020

What is Git?

What is Git? Today most software development projects are collaborative efforts. These projects can have hundreds or thousands...
28/12/2020

GitLab Container Registry Setup

In our last post we showed you how you can set up a GitLab instance to manage your organization’s or your personal projects....
28/12/2020
Bài Viết

Bài Viết Mới Cập Nhật

Mua Proxy V6 Nuôi Facebook Spam Hiệu Quả Tại Onetcomvn
03/06/2024

Hướng dẫn cách sử dụng ProxyDroid để duyệt web ẩn danh
03/06/2024

Mua proxy Onet uy tín tại Onet.com.vn
03/06/2024

Thuê mua IPv4 giá rẻ, tốc độ nhanh, uy tín #1
28/05/2024

Thuê địa chỉ IPv4 IPv6 trọn gói ở đâu chất lượng, giá RẺ nhất?
27/05/2024