How to PROPERLY git squash commits [Practical Examples]

 

Getting started for git squash commits

Doing git squash commits organizes your commit history. The commands to use during interactive rebase or git merge are:

git rebase -i <head>

to join commits, downwards, from the head or

Advertisement
git merge --squash <branch>

to group the target branch's commits before merging the feature branch with the main one.

On the flip side, you should not use git squash git commits if you plan to recover the mini-commits. We shall do some practice in this tutorial to ease understanding of when and how to use git squash commits.

 

The need for git squash commits in git workflow

Before diving into the practical usage of git squash commits before git push, you should understand what lies in git merge vs rebase.

You could handle a git workflow with one main branch. You keep adding files to the staging area and committing them. Sometimes you undo specific undesired commits or recommit them.

Soon the project has massively grown that you invite other developers to join you, working on various mini-sections of the project. That is when branching comes in.

Your teammates open different branches and commit multiple changes in them. Depending on the merging model, the repo may appear disorganized such that tracking the logical order of commits becomes hectic.

Advertisement

Although git rebases may help create a linear repo, it can lead to more conflicts when many developers keep appending commits to the head of the main branch.

The best solution for either problem is to use git squash commits. The commits entering the main branch become comprehensive and manageable.

 

Lab setup to explain git squash commits

Let us create a local repo, and a remote one to practice git squash commits before and after push. We use the local repo for squashing with interactive rebase, whereas the remote repo helps with the merge squash.

I am creating local repo, squash_with_rebase

mkdir squash_with_rebase

followed by a remote one on Github called git_squash_lesson.

How to PROPERLY git squash commits [Practical Examples]

Copy the clone URL

Advertisement

How to PROPERLY git squash commits [Practical Examples]

and move to the command line and clone the repo locally.

How to PROPERLY git squash commits [Practical Examples]

Now that we have two repos to practice git squash commits, let us build and modify them depending on our needs.

 

Example-1: Use git squash commits before git push

Navigate to the squash_with_rebase directory

cd squash_with_rebase

and start building the commit history.

Run

git init

to instantiate a new repo in the directory.

Advertisement

Create some files.

touch one.txt and two.txt

Stage the files.

git add .

Commit them.

git commit -m "add one and two"

Check the commit history.

git log --oneline

We have one commit history in the master branch and a branch.

git branch

How to PROPERLY git squash commits [Practical Examples]

Assume we want to work on feature_A, test, and combine its commits with the main repo. Create the branch and check it out using either:

Advertisement
git branch feature_A

git checkout feature_A

or

git switch -c feature_A

Build the commit history in feature_A.

touch dev.py

git add *

git commit -m "first python file"

Check the history.

git log --oneline

How to PROPERLY git squash commits [Practical Examples]

Repeat the process with the auth.py file.

touch auth.py

git add *

git commit -m "second python file"

git log --oneline

How to PROPERLY git squash commits [Practical Examples]

We shall repeat the process with the final commit in the feature_A branch. This time around, let us append a line in the dev.py file.

echo plan="devs here" >> dev.py

git commit -am "third python change"

We have three commits in the feature_A branch, totalling the directory commits to four.

Advertisement
git log

How to PROPERLY git squash commits [Practical Examples]

Check out the master branch and rebase the feature_A branch.

git checkout master

Master still has one commit in the history.

How to PROPERLY git squash commits [Practical Examples]

Let us rebase the branch.

git rebase feature_A

A peek at the commit history shows we have an easy-to-understand commit history.

git log

How to PROPERLY git squash commits [Practical Examples]

As we are about to push the changes we stop for a second and think, "Won't the history look nicer if we combined all the python commits into one?"

Sure, let us do that!

Advertisement

Run the command:

git rebase -i HEAD~3

to act on the last three commits from the head.

Git opens our favourite editor, where we can handle git squash commits. Since my default editor is visual studio code, git opens it.

How to PROPERLY git squash commits [Practical Examples]

There are many rebase options, the default active one being pick.

Let us change the two pick options from the top to squash options before closing the text editor.

How to PROPERLY git squash commits [Practical Examples]

So, what do pick and squash mean in git? pick is an option asking git to show us the changes at every commit hash. By replacing pick with squash for 2/3 commits we are telling git, "Hey git, melt down the 2 squashed commits into the picked one."

Save the changes and close the editor.

The editor reopens, promoting us for a commit message.

How to PROPERLY git squash commits [Practical Examples]

I am commenting out the two last commits and editing the commit message on line 4 from "first python file" to "add python files" then closing the text editor.

How to PROPERLY git squash commits [Practical Examples]

You see a success message on the command line similar to the one in the screenshot below

git squash commits from the head commit

Recheck the history.

git log

Our three python commits got squashed into one with a new commit message.

How to PROPERLY git squash commits [Practical Examples]

Let us see a similar scenario with a git merge.

 

Example-2: Use git squash commits after git push

You can apply git squash commits after pushing commits to a remote repo using the git merge squash command.

cd into git_squash_lesson directory.

Build the disorganized commit history before tidying it up with git squash commits.

Run

git init

in the project directory if you did not create a README.md on Github otherwise Github initialized a repo, did the primary commit, git added, and git committed it for you.

Create more files in the folder.

touch file1.txt

Stage the file.

git add .

Commit them.

git commit -m "track file 1"

Check the commit history.

git log --oneline

We have two commits in the main branch

and one local branch.

git branch

How to PROPERLY git squash commits [Practical Examples]

Assume we want to work on a feature in branch_B, test, and merge its changes with the main branch's commits. Let us create the branch.

git switch -c branch_B

Let us build the commit history in branch_B.

touch index.js

git add *

git commit -m "first js file"

Repeat the process twice with a different file.

touch dev.js

git add *

git commit -m "second js file"

touch auth.js

git add *

git commit -m "third js file"

Running the command

git log

shows we have added three js commits to the history.

How to PROPERLY git squash commits [Practical Examples]

Let us push the commits throughbranch_B.

git push --set-upstream origin branch_B

How to PROPERLY git squash commits [Practical Examples]

and refresh the remote, then check the commit history in branch_B.

How to PROPERLY git squash commits [Practical Examples]

Click, Compare & pull request and follow the guidelines till all the changes get inserted into the main branch.

How to PROPERLY git squash commits [Practical Examples]

Return to the command and continue with git squash commits.

Check out the main branch and complete git squash commits using merge squash.

git checkout main

git merge --squash branch_B

git squash commits using merge squash

Checking the status shows we have staged files.

git status

How to PROPERLY git squash commits [Practical Examples]

Let us commit and push them with the -f flag to discard the error message presented.

git commit -m "track js files"

git push -f

How to PROPERLY git squash commits [Practical Examples]

Return to the browser and refresh the remote repo's page.

All the .js files now have a similar commit message meaning our git squash commits were successful.

How to PROPERLY git squash commits [Practical Examples]

And that is how to git squash commits after push using the git merge --squash <branch> command. You can achieve a similar result by applying the interactive rebase command we learned in example-1.

 

Conclusion

You have just learned how to tidy up your commit history through git squash commits. Now is the time to simplify your file tracking by practicing the tricks you learned in this tutorial.

 

Categories GIT

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X