Anyone working with version control software such as Git will eventually come across a merge conflict. If you are new to working with Git, here is a simple example of a merge conflict:
The master branch contains a file with this text:
Kristin Jackvony was here on May 22, 2019
Prunella and Joe each check out a version of this master branch. Prunella makes a branch called “Prunella” and Joe makes a branch called “Joe”.
Joe updates the file in his branch to read:
Kristin Jackvony was here on May 22, 2019
Joe Schmoe was here on May 23, 2019
Joe does a pull request for his file changes, and they are approved and merged into the master branch.
Shortly thereafter, Prunella updates the file in her branch to read:
Kristin Jackvony was here on May 22, 2019
Prunella Prunewhip was here on May 23, 2019
She also does a pull request for her file changes, but because she no longer has the latest version of the master branch, there is a merge conflict. Git sees that she wants to add her name to the second line of the file, but her version of the master branch doesn’t have anything on the second line, whereas the new version of the master branch already has Joe’s name on it. Prunella will need to resolve the conflict before her changes can be merged.
I’ll be honest; I really wanted to master resolving Git merge conflicts for this post. However, resolving them from the command line still confounds me! Fortunately, I’ve found a number of different ways to handle merge conflicts so that they no longer fill me with dread. Below I’ll discuss six steps for handling a conflict.
Step Zero: Avoid Having a Merge Conflict In The First Place
By using the helpful hints in last week’s post, especially tips one, two, and six, you can avoid creating a merge conflict. Doing a pull from master is always a good idea before you do anything code-related.
Step One: Don’t Panic
When you have a merge conflict, it’s important not to thrash around trying “git this” and “git that”. You might make things more confusing this way. A merge conflict will eventually be solved, even if you have to resort to asking for help (Step Seven). And you can’t possibly have done anything irreversible; that’s the beauty of version control!
Step Two: Resolve the Conflict from Within GitHub
GitHub has an easy interface that will allow you to resolve merge conflicts. Simply click the Resolve Conflicts button and observe the conflict. It will look something like this:
>>>>>HEAD
Joe Schmoe was here on May 23, 2019
=====
Prunella Prunewhip was here on May 23, 2019
<<<<< Prunella
All you need to do is decide which entry you want to go on line 2, and which entry you want to go on line three, and make those edits, deleting the extraneous symbols and branch names along the way. When you are done, your file will look like this:
Kristin Jackvony was here on May 22, 2019
Joe Schmoe was here on May 23, 2019
Prunella Prunewhip was here on May 23, 2019
Now click the Mark as Resolved button, and your pull request should be ready for merging.
Step Three: Resolve the Conflict from the Command Line
If you are using Git as a version control system, but you are not using GitHub to host your repositories, you may not have a nice UI to work with in order to resolve your conflict. In this case, you may need to use the command line.
What I do in this scenario is open the file with the merge conflict in a text editor such as TextEdit or Notepad++, I edit the file so that it looks the way I want it to, removing all the extraneous symbols and branch names, then I do a git add with the filename, and then a git commit. I do this in accordance with the instructions found here: https://help.github.com/en/articles/resolving-a-merge-conflict-using-the-command-line. However, I have only had success with this once or twice. Usually I have to go on to Step Four or Step Five.
Step Four: Forget About Your Existing Branch and Make a New One
In this scenario, I copy the text of the entire file with all my changes, and I paste it somewhere outside the code. Then I go to the master branch and do a git pull origin master. Now I should have all the latest changes. Then I create a brand new branch, switch to that branch, and paste in all of my file changes. Then I do a fresh new pull request, which won’t have a merge conflict.
Step Five: The Nuclear Option
If Step Four failed to work, I exercise the nuclear option, which is to delete the entire repository from my machine. Before I do this, however, I make sure to make a copy of my file with all my changes and paste it somewhere outside the code, as I did in Step Four. Then I delete the entire repository and clone it again. Then I continue as I did in Step Four, creating a new branch and switching to it, making my changes, and doing a brand new pull request.
Step Six: Ask For Help
If all else fails, ask someone for help. There’s no shame in asking for help with a particularly thorny merge conflict! If you followed Step One and didn’t panic, your helper will be able to see exactly what you’ve done so far and can help you arrive at a solution.
Git purists may argue that merge conflicts should be resolved the right way (using Step Two or Step Three), and they are probably right. But doing Step Four or Step Five can keep you from wasting time trying to resolve the conflict, and they also will keep you from defenestrating your laptop!
Resolving merge conflict is no more undigestable task to me. These steps are simple and easy to understand. You write blogs exactly what a Tester need. Thanks to your good work.
Thanks, Somasundar!