Git is indeed an ocean of topics to dive in and one can learn these only if you use them and experience them. So, here I am with another of my learning. If you work for a project, there are probable chances that you come across using rebasing. So what exactly is rebasing? Let’s know about it.
In open source contributions, one follows certain rules and regulations while contributing. Each organization has these rules defined in specific file, most of the time, you would see something similar as CONTRIBUTING.md. So, more often you’ll be asked to work on a separate branch for each issue/feature you are working on. This branch is called as feature branch. Since you are working on different branch, you would want to keep your branch updated with master of upstream. So, do you know how would you do it?
Well of course you know it. You would simply do `git pull upstream master` and your branch will be up-to-date with master. However, this will result in superfluous merge commit that would intervene your commit history. You might not want to clutter your commit history with these merge commits each time you do git pull. So to avoid this we have a wonderful tool ie rebasing.
What does rebasing do?
Even if you mean it literally, you can tell its purpose. It re-base the commits of current branch on the top of other branch’s. Did it confuse you? No problem. Let take an example. So suppose you are working on a project which has the following commit history :
And then you created a feature branch and did few commits on it, that would be like:
A-B-C-D (master) \ E (feature)
However, during the period you were working on your feature branch, the work on master branch proceeded and there have been few more commits on master branch and in your feature branch. And now your commit history looks like this:
A-B-C-D-H-I-J-K-L(master) \ E-F-G (feature)
But now you need those commits of master to get up-to-date in your feature branch. So, what would you do? Indeed we can do rebasing. But what if we do simple merge? Let’s see
So for merge you would enter the git command as:
git checkout feature git merge master
And then your commit history would be like this:
A-B-C-D-H-I-J-K-L(master) \ / E-F-G-M (feature)
Since you merged the master branch into feature branch. The commit M has got created which is a merge commit. It would contain the changes in the master branch and would add it to your feature branch.
There is one thing to notice here which is that there is no effect/change on the previous commits of any of the branch.
Finally, what would have happened if we had done git rebase instead of git merge. Let’s see that also. So for rebasing you would enter the git command as:
git checkout feature git rebase master
Now is the time where you should know how rebase works. It re-base ie change the base of your feature branch on the top of the HEAD of master branch. What’s the base of your feature branch now? Yup! it’s the commit D. After rebasing it would shift to the commit L. It would look like you had implemented your work on the top of what everybody has already done. During rebasing following steps are taken:
- It finds out the common commit of your current branch(feature in our case) and the base branch(master in our case) which is the commit D(here).
- It then collects all the commits between that common commit(D) and the HEAD commit(G) of current branch. And put those commits aside. In our case these commits are E, F and G.
- It shifts the base from that common commit to the HEAD of the base branch(L in our case).
- It re-plays each change which were set aside, on the top of new base and creates a new commit.
Now, the base of your current branch ie feature branch is the HEAD of master branch. You might have noticed those bold words in the last step. That was intentionally done to point out that all the commits of current branch from the base commit to the HEAD will have a different commit hash value. As because they have been re-committed after the base got changed. This was all done during the rebasing process.
After rebasing your commit history would look like this:
A-B-C-D-H-I-J-K-L(master) \ E'-F'-G' (feature)
Now your base has changed from commit D to commit L.
E’, F’, G’ refers to the new commits which have been done during rebase. Each of them corresponds to the changes that have been done to commits E, F, G respectively.
While doing merging, we usually come across merge conflicts. Merge conflicts arise when there is a change in same file and in same line in two different branches. Git doesn’t know that while merging which change should it consider. So, it is our responsibility to first solve that conflict and then again try merging.
Since rebasing is actually a type of merging just the difference is that first it changes your base and then apply the changes of current branch. So, there is again chances that there could be some conflicts. Rebasing stops at the moment where it finds any conflict and asks you to resolve the conflict. Though after resolving the conflict, you don’t have to start rebasing again as it is already in progress. It just stops momentarily until you resolve the conflict. Once you are done with resolving, you can continue rebasing using the command:
git rebase --continue
And then it would apply the remaining commits. However, if at any moment you feel like you don’t want to continue with the rebase, you can abort the rebasing using
git rebase --abort
You would be at same stage as you were before starting rebasing.
When not to use rebase?
Even though there are advantages of rebasing, it can be troublesome sometimes. You should always remember not to rebase a public branch. It means that you shouldn’t try to rebase a branch that other people might have forked. As rebasing changes your commit history. That could lead to confusion and conflicts. I again say Do not ever rebase public branch.
However, rebasing private branches is totally fine and often recommended.
So, now you know rebasing. Well it’s not yet done. There are a whole lot of things you can do with it. We’ll cover it in another blog post.
I have gone through many links and posts to learn rebasing. So, I would suggest you to go through the same to get more insight about it.
Goodbye for now. Hope it was helpful.
Till next time, be curious and keep learning!