Merging in Git: A Refresher for Beginners
Recently, I have been working again more with version controlled projects using git
.
Since I have not been using git
very long, each time I come back to it I must refresh myself with the ins and outs of merging.
From a novice perspective, I think that merging is a kind of bifurcation point along the journey of becoming a better git
user.
One can either persevere and figure it out or it can always be a painful process.
But if one can make their way through the minefield which is merging using git
when starting out on your git
journey, then later concepts such as reverting or re-basing are grasped quicker.
But for now as a relatively novice git
user, I have found myself struggling through understanding the basics of git
merging once again so I decided to write down in this post the key points which I have come up with to better understand git
merging.
So here it is.
First of all, basic git
merging can be thought of in two scenarios. One scenario for a fast forward merge and another scenario for a 3-way merge.
Now if those terms mean nothing to you, stay with me.
For the first case of the fast forward merge, consider a situation where you have your master
branch and a second branch which I will call the hotfix
branch.
In software projects, this type of branch, hotfix
, would contain some really important and quick fix that needs to be accomplished.
This branch, hotfix
, can be 1, 2, 3, or even more commits ahead of the master
branch but the most master
branch is the direct ancestor of the series of commits contained in the hotfix
branch.
So in this situation all that git
has to do is move up the pointer of the master
branch (currently point N commits behind the last commit of the hotfix
branch) to the last commit within the hotfix
branch.
That seems simple enough.
Just move the pointer up.
Before merge. | After merge. |
---|---|
Now for a little more complicated case, the 3-way merge.
In this scenario, again consider 2 branches.
A master
branch and a issue
branch where this new branch is similar to a branch that would be created for a longer term fix which is needed to correct a issue with the overall software project.
The difference in this scenario to the previous one is that the commits (specifically the last commit) of the master
branch is no longer the direct ancestor of the issue
branch.
This means that while you have been working on the issue contained within in the issue
branch, someone else committed new code to the master
branch.
Before merge. | After merge. |
---|---|
However, there is still a common ancestor for which both branches point back to.
You just have to look a little further back in the commit history.
And luckily enough git
is powerful enough to determine this common ancestor by itself.
Then you can either win the lottery of lose.
By this I mean that if the changes in each branch (i.e. master
and issue
) do not change the same lines of code, then git
is able to automatically finish the 3-way merge by creating a new commit with all the changes from both branches.
But if not (which is most of the time in reality), git
pauses the automatic process and present you the git
user with a message stating that their is a merge conflict.
I know scary sounding but really not that bad.
Git
adds conflict markers which tell you where conflicts exist and what each branch ``thinks'' is the ``right answer''.
You can then go into these files and manually clean it up and fix the conflict and commit the new result.
While you are committing the new result, git
will ask you if you want to finish the merge process and end up with the final merge commit as if you had won the lottery (i.e. no conflicts).
And that is it.
Git
merging is that bad, is it?
I do not think so once you get the hang of it.
Git
itself is very powerful but also helps out with verbose messages to the user.
And especially if you are willing to learn something new, then merging using git
should not be scary but exciting.