James C Koch CV Blog Portfolio Publications DE

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.
simplefastfowardmerge-beforemerge.png simplefastfowardmerge-aftermerge.png

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.
threewaymerge-beforemerge.png threewaymerge-aftermerge.png

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.