Git Merge vs Rebase

Git Merge vs Rebase

When working with Git, we frequently create branches to isolate specific features or address bugs. Eventually, we'll need to integrate changes from these branches into our main codebase. Git offers two primary methods for combining branches: git merge and git rebase. These techniques serve distinct purposes and come with their own advantages and trade-offs.

Suppose you are working on a feature. And for that feature, you are working on a new branch named 'feature'. You have done your work, and the work tree looks like the one below.

Untitled Diagram.drawio.png

While working, some other teammates pushed some commits to the main. Before creating a Pull Request (PR) for your feature branch, you want to ensure it includes the latest changes from the main branch. To do this, switch to the main branch and pull the latest updates from the remote repository.

git checkout main
git pull origin main

After the above commands, your work tree looks like the one below. (Assuming only one new commit was pushed to the main)

Untitled Diagram.drawio (10).png

To have the new changes of main in your feature branch, you can either use git merge or git rebase. The goal of the two commands is the same, but they work differently. Let's first understand the git merge feature.

Git merge

Now to merge the main to feature branch. We checkout to feature and merge the main.

git checkout feature
git merge main

Or shortcut for this command is:-

git merge feature main

It creates the following work tree.

Untitled Diagram.drawio (2).png

The *(star) shows the extra git commit created while merging.

Note:-

There are two ways, either we merge main onto feature or feature onto main. In some cases, when we have push access to the main branch, we don't create PR, we merge feature branch into the main directly. In such case we do git merge main feature. The working tree in this case looks like the one below:-

Untitled Diagram.drawio (3).png

While using git merge, the existing branch is not changed, which is a good thing about it. It's easy to use with no complications. However, it introduces extra merge commits into the commit history, which can clutter the tree and disrupt the linear working tree structure.

Fast forward merge

Fast forward merge happens when there is no new commit in the main branch like below.

Untitled Diagram.drawio (7).png

In fast forward, we don't see the extra git commit.

Untitled Diagram.drawio (9).png

Git Rebase

Let's perform the same thing using git rebase.

Untitled Diagram.drawio (10).png

git checkout feature
git rebase main

Untitled Diagram.drawio (3).png

The * says it is creating new commits.

Wow, we can see the difference, the history looks so clean, all linear with no extra git commit. This is one of the reasons people love rebasing. But, we can see that the history is changed, in place of original commits, new commits are added.

Note:-

If the branch is already in remote, you might face problems while pushing it. Git won't allow pushing. You may need to "force push" the commit in such a case.

git push origin feature --force

Force push is not bad if you know what you are doing. But be cautious when you are force-pushing a public branch.

Now, consider the second scenario, rebasing the main onto the feature branch.

git checkout main
git rebase feature

In that case, the work tree will look this:-

Untitled Diagram.drawio (5).png

The * says it is creating new commits.

You will need to "force push" the main branch, as git won't allow it. But stop. It can be dangerous. The other people working on the main can have some problems. The git will think their branch has diverged and when they pull the commits from "main," it will result in more extra commits created. It will be very confusing for all other people.

So, remember this rule. Never rebase a public branch. Rebase only when you are the only one working on that branch.

Conclusion

Both git merge and rebase have their own pros and cons. But you should know when to use which. It's not a hard and fast rule but it is recommended to use merge when you are working on a public branch and rebase on a private branch.

Suppose you are working on a feature that is expected to take a long time. So, while working, you want to keep your feature branch updated with the main. The best way is to use git rebase here; you won't create the extra git commit made with "git merge". Your feature branch work tree will be clean, linear and up to date.

Thanks, for reading, please drop a like, if it was valuable to you.

Also, do follow me on Twitter, https://twitter.com/DevTalesShrey