Merge vs rebase strategies with git
Author: Adem Usta
Published on 2020-08-01
One of the best practices as a developer is to use code versioning software to maintain their project.
In this context, the open-source software git helps the developers a lot.
It allows the developers to version their application source code, so they can keep old versions of their software.
It also allows several developers to work on the same project at the same time, well at least in theory if git is well used.
I will expose in this article a classical situation where an application is enhanced with new features by several developers.
Here is the context:
- a single project which its source code hosted on GitHub.
- several developers are working on the same file, and potentially are modifying the same part of it.
The main branch of the project is named master, as in a lot of git projects.
The branch master already contains some commits:
Source code modified by several developers
Let’s say there are two developers A and B. They want to add some new features in the project.
The best practice is to create a new branch for each feature, and add their feature into. I will name those branchs branch-A and branch-B.
When they’re done, A and B will want to merge their branchs into master, to let their new feature be on production.
It’s at this moment that developers have to choose between two possibilities:
Here are the branchs state:
In the following, I suppose that A will push his changes into master first.
He creates a pull-request, and after validation by the team, he merges branch-A into master. The schema becomes:
Until there, nothing really fancy.
But when B wants to do the same with his branch, things gets interesting.
As shown in the branchs network, master has changed thanks to A, and branch-B does not have these changes.
It’s at this moment that the choice between
rebase must be done.
I will experiment the two ways, and see what it implies on the network, potential conflicts, etc.
By choosing a merge strategy, git will naturally take all your branch commits and add them to master, here is the result:
Note: the colors does not represent the same branchs from one image to another, thank you GitHub !
Note 2: another developer C added a new branch, it will be used to show the rebase strategy.
The graph shows that the branch network is not readable.
Moreover, there only are a small amount of developers !
Imagine with 10 or 20 developers, doing some merge directly …
In this context, I will show how a simple rebase could do the trick and make the network looks more readable.
A new developer C is now part of the project.
He has his own branch branch-C in which he’s working on a new feature.
Comes the moment when he wants to push his changes on master.
His pull-request gets accepted, he decides to do a rebase before merging.
Note: to perform a rebase before merging, you can do this either by the CLI in you workstation, or directly on GitHub.
With the CLI:
git fetch && git rebase origin/master
At this moment, if you have some conflicts with the master branch, you need to resolve them.
Then you need to push force your branch to the remote one.
This (push force) can be problematic in some cases, for example when you are more than one developer working in the same branch.
Else, you can to the rebase before merging in GitHub directly:
In this case, github does not show branch-C, but the commits on this one are now in master: the last ones are the branch-C ones.
To show what a rebase with the CLI does, I add another branch-D :
After rebasing + push force, the network looks like:
The graph shows what a rebase does here: git moved our branch branch-D at the top of master, and then it replays all of our branch-D commits to see if there is any conflicts.
If there is any, you need to resolve them at this moment.
All I have to do is merge the branch with the GitHub interface. The network looks like this:
Here, we see that branch-D (the one in blue, at the top) went up.
The interest of this strategy is to have a network more readable, with master that follows a straight line, and merged branchs to be “separated” in the network (each merged branch form a single loop to master, without overlap).
There is a caveat with this strategy: the push force is mandatory.
In the case where there are several developers that are working on the same branch, be sure to pull all your collegues work locally before rebasing and do a push force.
If you don’t do that, you will potentially delete your collegues work.
merge strategy is straightforward, the workflow is simple:
- I develop on a new branch our new feature
- Once ready, I open a pull-request
- Once validated, I merge it
But this implies a network not really readable (in my opinion).
rebase implies more discipline:
- I develop on a new branch a new feature
- Once ready, I open a pull-request
- Once validated, I do a rebase
- I merge the pull-request.
The workflow is more complicated, and requires some discipline. But the result is a better branch network.
That’s it for my first article ! If you have any question, please feel free to send me an email !
See you soon,