DEV Community

Cover image for Git Merge vs Rebase and Where to Use Them
Mohammad-Ali A'RÂBI
Mohammad-Ali A'RÂBI

Posted on • Edited on • Originally published at Medium

Git Merge vs Rebase and Where to Use Them

There are two workflows for merging a feature branch into the master branch, namely 'rebase and fast-forward' and '(proper) merge'. In the previous article, we have discussed what each of these workflows means. Now, it's time to discuss when to use them.

TL;DR

It is recommended to read the prequel before jumping into the discussion.

To Merge or to Rebase

It depends. I'll mention some pros and cons and will say what is the way I personally do it.

Git Graph

The first feature of the real merge is the non-linear and sometimes messy git history graph that it creates. Using the merge workflow, your history will also be filled with merge commits that are always the same: this branch was merged into the other one. It does not tell much, it just points you in some directions.

Let's assume that you want to keep your branch up-to-date with master while developing. The graph will become horrifying.

Git graph

This is not the case with rebasing, as it just puts your branch commits on top of the commits from the master.

Commit Messages

We mentioned that merge commits are annoying. But let's assume you have a branch with 79 commits, each of which has a message similar to "big fix" or "update README". By doing a rebase and fast-forward, you're adding a lot of junk to your master. A real merge is also not a good option here: the merge commit points to the pile of junk. Perhaps a squash merge makes the most sense here.

But if you have one or two well-crafted commits, with meaningful messages, it makes better sense to add them to the master branch directly, instead of adding another "Merge branch feature_branch".

Update the Feature Branch

Let's assume you want to get the updates from the master branch and them to your feature branch. If you have 79 commits, and there is a conflict, in the case of a rebase, you might be forced to resolve the conflicts 79 times (because the commits are added one by one to the tip of the master). This is not the case when you create merge commits.

My Personal Recommendation

The final answer to "which one to use" is "it depends". None of them is a silver bullet, and you can make a mess out of both if you don't use git properly.

The workflow I use is based on rebasing and fast-forward, but it's also very similar to the squash merge:

  1. Create a feature branch for a small change
  2. Add a few commits
  3. Create pull/merge request
  4. After the pull/merge request is reviewed and accepted, squash the commits on the feature branch into one (manually, without merging) and write a meaningful commit message for it, linking the original issue ID
  5. Perform a fast-forward merge to master

I like keeping the master branch clean and linear, and every commit message meaningful. It helps when someone wants to get more context about certain changes in a codebase (by doing a git blame).

The other reasons I follow this workflow:

  • I do small commits to make the review process easier for the reviewer
  • After the review is done, I squash them together, so that only one commit ends up on the master branch
  • I squash manually because then the commit message can be reviewed before the final merge (or even checked automatically by the CI)
  • Furthermore, with a manual squash, I can write the commit message myself — with a squash merge, the one who clicks the merge button gets to write the commit message, which is not preferred
  • I do one thing per pull/merge request, so it makes sense to have one commit for it
  • I link back the original issue number/ID to the commit message, both to automate closing the issue (GitHub and GitLab have mechanisms for that) and to give the future reader an opportunity to look into the discussions and requirements of that issue

Future Work

In the next article, I'll discuss how to squash commits manually.

Top comments (0)