Rebase, merge or squash, which should I use?

Rebase, merge or squash, which should I use?

Hi guys, in a git talk I gave, one of the questions that generated the most discussion was, when should I use merge, rebase, or squash when trying to join two branches in my repository.

When we are working in a team it is important to use Git and the repository in a proper way in order to maintain efficiency and good communication regarding the changes we make in the repository. Keeping the GIT repository with a clear, tidy, and clean history is important. Many times reviewing this can save us hours and understanding how the project has been developed.

This post seeks to comment on my experience when you can use merge, rebase, or squash. I also explain how the history is treated in the repository so you can understand and decide which one to use when you need it.

About the symbols in the examples

In the following examples we are going to use the following symbols

develop branch

  1. The lines represent the branches
  2. All the color figures represent a specific commit in the repository
  3. The commits are ubicated chronologically
  4. The branch development will be the main branch of the project
  5. The branch feature represents some new implementation of something
So with this clear, let deep dive into the rebase:

Rebase

In this scenario lets assume that we work on new feature, but to achieve the goals of this feature we created many important functions, and each of these functions has its own important commit, as we show in the next picture

feature

In this scenario let’s assume that we work on the new feature, but to achieve the goals of this feature we created many important functions, and each of these functions has its own important commit, as we show in the next picture

rebase

Rebase do some actions in our repo:
  1. Copy the new commits at the end of the develop branch.
  2. Delete the feature branch, we don’t need the branch because we already have all the commits in the develop branch, so the history is in order and correct,
The outcome of the repository should looks like this:

rebase final

As you can see, our history repository has its history in order, so using a rebase is a good approach if we want to carry all the commits to the main history because it maintains everything in order.

Merge

let’s use the previews scenario, we had our repository like this:

feature

We need to join the feature branch into the develop one, we need to preserve the history of the commits, but we are going to use merge, so let’s see the result of this method:

feature merge

You can see that merge creates a new commit with all the changes, but if we want to see the history of this feature we need to change the branch into the feature, so we can see all the commits. This method helps a lot when we are updating our branches, for example, if we want to carry on the new changes on the develop branch into the feature, we can use merge because we don’t need all the commits into the feature, because sooner or later we are going to join the feature to the develop branch.

Squash

In this scenario let’s imagine that we create an experimental branch because we are working on some complex function.

exp branch

We can notice that the experimental branch has five commits about the same function. At the fifth commit, we accomplish the objectives of the function. In this case, the most important part of the experimental branch is the result of the function, we don’t care about how we get to the final solution. In this case, making a merge could work but we are complicating the history of the repository, if we think about rebase the problem is that we are adding the fifths commits to the develop branch, and we don’t want that.
In this case, making a squash is the best approach to the solution:

exp branch 2

  1. The squash adds only one commit to the development branch with the final changes of the experimental branch.
  2. Squash removes the experimental branch from the repository, so we can have a clean and understandable history.
In the next picture, you can see the final result of the repository.
squash
and, tell me, how do you implement this?
moroquin Avatar