Merge and Rebase in Git
Previously, we have seen a few strategies for fixing mistakes, but most importantly, preventing those mistakes. And as seen, a great way to avoid conflicts and mantaining the single-responsability paradigm is using branches to make sure different parts of the development are isolated.
We can´t, however, expect our project to remain in bits and pieces forever, we need them to assemble them in order to access a fully functional program.
That's where merging comes into play. As the name suggests, it is the joining of two branches. Or, to be more precise, it is incorporating commits from branch B onto branch A.
Merging
If, for instance, you'll write code for a new feature for your program. You decide to use a new branch for that. No problems there, but what about when you finish the new feature, it must be integrated to the whole project.
In order to acomplish that, checkout into the main
.
Terminalgit checkout mainCopiar
Then it is only a matter of bringing the feature commits onto this branch and fixating them with a merge commit.
Terminalgit merge feature_branchCopiar
The direction of the merging is always bringing from the specified branch to the current one and it will bring up to the last commit.
That does not mean, however, that we will always merge from a feature onto the trunk. Sometimes quite the oposite.
If you were working on a feature on a specific branch and some new changes were commited to main and those changes were relevant to your feature, you might want to keep those updates.
The procedure would be a little bit different. Instead of checking out to main, you'd be on the feature branch and merge the new additions from main.
Terminalgit merge mainCopiar
From then on, the new changes will have been incorporated onto the branch. Besides that, both branches remain, nothing else.
One possible set back of merging is keeping track of the branches history. The merging process will result in many more commits described and that can be perceived as a little polluted, specially if the main branch is very active and you must merge commits from it frequently.
Rebasing
Rebasing is an alternative to merge, which will lead also to an integration of new work into a different branch. Rebasing, however, will not preserve branch history.
While merging will create a new commit for every integration showing how and when the branches were combined, rebase will procede slightly different.
For instance, if we were to rebase feature onto main, rebasing will rewrite the history of the feature branch making it as if the begining of it was the last state of main and features commits were sequential to those on main.
That will turn what was a parallel project, developed across multiple branches, into a linear one, as if it had been created so in a single branch.
It results in a much clearer history, easier for git log
or git bisect
.
The Golden Rule of Rebasing
As you can imagine, rewriting the history of a repository can be quite dangerous if done on the wrong situation. Luckly, there is a golden rule
for rebasing:
Never rebase a public branch
If you were to do so, for example, if you rebased main onto your feature, you'd end up with a whole different main than anyone else.