ūüéČ

Hatica announces v3: Closing the loop on Driving Engineering Productivity ūüéĮRead More >

Tools2023-06-26

Squashing Git Commits: Benefits and Best Practices

Optimize Git collaboration using commit squashing. Merge commits using real code cases for a tidier, more coherent history and enhance code clarity.
Squashing Git Commits: Commands, Benefits, and Best Practices

Git, a widely used version control system, provides various powerful features to manage and organize project history effectively. One such feature is squashing commits, which allows developers to combine multiple commits into a single cohesive commit. This process not only simplifies the commit history but also enhances collaboration and code readability. In this article, we will explore the concept of squashing commits in Git and demonstrate how to leverage this technique to maintain a cleaner and more streamlined Git history.

Understanding Git Commits

Before diving into squashing commits, let's briefly understand the basic structure of Git commits. Each commit in Git represents a snapshot of a project at a specific point in time. Commits contain a unique identifier (SHA), author information, a commit message, and references to parent commits. The commit history forms a directed acyclic graph, enabling easy traversal and tracking of changes made over time.

What is Commit Squashing?

Commit squashing involves combining multiple commits into a single, well-structured commit. By squashing commits, developers can condense a series of small, incremental changes into a single meaningful change, making the commit history more coherent and comprehensible. Squashing is especially useful when preparing a clean and concise commit for code review or before merging into a main branch.

Squashing Commits with Git Commands

To squash commits using Git commands, follow these steps:

Step 1: Identify the commits to squash

Use the git log command to view the commit history and determine the commits you want to squash. Note down the commit SHAs or relative references.

$ git log

commit 12a34bc (HEAD)

Author: John Doe <myexample@example.com>

Date:   Mon May 20 10:00:00 2023

    Implement feature XYZ

commit 56d78ef

Author: John Doe <myexample@example.com>

Date:   Fri May 17 14:30:00 2023

    Refactor code for improved performance

commit 90e12ab

Author: John Doe <myexample@example.com>

Date:   Wed May 15 09:45:00 2023

    Initial implementation of feature XYZ

Step 2: Initiate an interactive rebase

Run git rebase -i <commit> where <commit> is the commit before the first commit you want to squash. This opens an interactive rebase session, presenting a list of commits in a text editor.

$ git rebase -i 90e12ab

Step 3: Specify the squash action

In the text editor, change the pick command to squash, s, or fixup for the commits you wish to squash. The squash command combines the commit with the previous one, while the fixup command discards the commit message.

Interactive rebase opens a text editor with the following content:

pick 90e12ab Initial implementation of feature XYZ

pick 56d78ef Refactor code for improved performance

pick 12a34bc Implement feature XYZ

Change the pick command for the commits you want to squash:

squash 56d78ef Refactor code for improved performance

squash 12a34bc Implement feature XYZ

Step 4: Edit the commit message (optional)

If you choose the squash command, Git will prompt you to edit the commit message. Modify the message to reflect the combined changes and save the file.

Git will prompt you to edit the commit message for the squashed commit:

# This is a combination of 2 commits.

# The first commit's message is:

Refactor code for improved performance

# This is the 2nd commit message:

Implement feature XYZ

Modify the commit message to reflect the combined changes:

# Combined commits:

Refactor code for improved performance and implement feature XYZ

Step 5: Complete the rebase

Save and close the text editor. Git will automatically squash the selected commits into a single commit. If conflicts occur during the rebase process, resolve them as instructed by Git. Save and close the text editor.

Step 6: Push the changes

After successfully squashing commits, push the changes to the remote repository using git push --force.

$ git push --force

By following these steps, you can squash multiple commits into a single cohesive commit, resulting in a cleaner and more concise Git history.

Note: It's important to exercise caution when using the --force option during a push, as it rewrites history. Be sure to communicate and coordinate with your team to avoid conflicts and ensure everyone is aware of the changes.

Benefits and Best Practices

Squashing commits offers several benefits, including:

1. Improved readability

By combining related changes into a single commit, the commit history becomes more cohesive and easier to follow.

2. Clearer code review 

Squashed commits provide a higher-level view of the changes, making it simpler for reviewers to understand the intent and purpose of the modifications.

[ Read more: Best Practices for Code Reviews ]

3. Streamlined branch management

Squashing commits helps keep feature branches clean and concise, reducing clutter and potential conflicts during the merge process.

To maximize the effectiveness of handling commit squashing, you should consider following the best practices:

  • Squash commits locally before pushing them to shared repositories.
  • Create meaningful and descriptive commit messages.
  • Review and test squashed commits before merging them into important branches.
  • Communicate with your team about your commit squashing practices to ensure alignment and avoid surprises

Is Squashing Commits a Good Idea?

Commit squashing can be a beneficial practice in Git, but it's important to consider whether it aligns with your project's needs and collaboration style. Here are some factors to consider when evaluating whether squashing commits is a good idea for your workflow:

1. Readability and Understanding

Squashing commits can improve the readability and comprehension of your commit history. Compressing related changes into a single commit provides a clearer narrative of the development process and makes it easier for others to understand the purpose and intent of the changes.

2. Code Review and Collaboration

Squashing commits can simplify the code review process. It presents reviewers with a higher-level view of the changes, reducing the cognitive load of reviewing numerous smaller commits. Additionally, squashed commits can enhance collaboration by fostering focused discussions around cohesive units of work.

3. Granularity and Debugging

Squashing commits sacrifices granularity, as individual changes are combined into a single commit. This can make it more challenging to pinpoint specific changes or debug issues that might arise. If detailed commit history is crucial for your project or if you frequently rely on Git's bisect feature for debugging, squashing commits might not be the best choice.

4. Branch Management and Merging

Squashing commits helps maintain a clean and concise history, particularly when merging branches. It reduces the clutter of multiple small commits, minimizes conflicts, and enhances the clarity of the branch's purpose.

Conclusion

Commit squashing is a valuable technique in Git that allows developers to create a more organized and coherent commit history. By combining related commits into a single unit, squashing improves code readability, simplifies code review, and facilitates better collaboration among team members. Understanding the process and following best practices ensures a cleaner and more streamlined Git history, making it easier to maintain and navigate projects over time.

Ultimately, the decision to squash commits depends on your team's preferences, project requirements, and collaboration dynamics. It's essential to communicate and align with your team members regarding commit practices to ensure a consistent approach and avoid surprises.

Subscribe to the Hatica blog today to read more about unblocking developers, and boosting productivity with engineering analytics. 

Share this article:
Table of Contents
  • Understanding Git Commits
  • What is Commit Squashing?
  • Squashing Commits with Git Commands
  • Step 1: Identify the commits to squash
  • Step 2: Initiate an interactive rebase
  • Step 3: Specify the squash action
  • Step 4: Edit the commit message (optional)
  • Step 5: Complete the rebase
  • Step 6: Push the changes
  • Benefits and Best Practices
  • 1. Improved readability
  • 2. Clearer code review¬†
  • 3. Streamlined branch management
  • Is Squashing Commits a Good Idea?
  • 1. Readability and Understanding
  • 2. Code Review and Collaboration
  • 3. Granularity and Debugging
  • 4. Branch Management and Merging
  • Conclusion

Ready to dive in? Start your free trial today

Overview dashboard from Hatica