We often create branches when we work on a particular feature or solve a bug. Later, we need to merge the changes across different branches. Git provides us two techniques to combine two branches, git merge and git rebase.
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.
While working, some other teammates pushed some commits to the main. Before creating the PR (Pull request) with your feature branch, you want new changes in your feature branch. We first move to the main branch and update it from the remote.
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)
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 are the same, but they work differently. Let's first understand the git merge feature.
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.
The *(star) shows the extra git commit created while merging.
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 into the main directly. In such case we do
git merge main feature. The working tree in this case looks like the one below:-
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. But, with git merge, the tree get polluted with extra merge commits and we don't get a linear working tree.
Fast forward merge
Fast forward merge happens when there is no new commit in the main branch like below.
In fast forward, we don't see the extra git commit.
Let's perform the same thing using git rebase.
git checkout feature git rebase main
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.
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:-
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 problem. 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 a lot 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.
Both git merge and rebase have thier 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 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 worktree will be clean and linear and up to date.