Friday, April 6, 2007

The order in your files, matters when merging...

This post is just some basics on how to behave well when dealing with merging changes from different branches.

A rather common scenario is to have a main trunk and then branch of a maintenance version and a production release and a ongoing project branch. When dealing with a structure like this there tend to be alot of different people involved and all that goes along with that.

So why does the order in your files matter then? Say for instance you have the following class:

    public class MyClass
    {
        public MyClass()
        {
        }

        public void DoWork()
        {
        }
    }


Then you find a bug in you production code which you have to correct asap and in the process needs to refactor the code for some reason ending up adding a new method to the class. Now our class looks like this in the production branch:

    public class MyClass
    {
        public MyClass()
        {
        }

        public void DoWork()
        {
        }

        public void OurNeatNewBugfixMethod()
        {
        }
    }


Then your people working in maintenance (maybe the same person that fixed the bug in the first place) have no patience to wait for the regular forward / reverse integration cycle between the branches and makes the correction in the maintenance branch as well. So far there is no problems, but what if someone else has added functions in the maintenance branch. No problems well just add the function last right? And the result would look like this:

    public class MyClass
    {
        public MyClass()
        {
        }

        public void DoWork()
        {
        }

        public void DoMoreWork()
        {
        }

        public void OurNeatNewBugfixMethod()
        {
        }
    }


So what's the deal? Why is this a problem? Well now the day comes when we do our normal forward / reverse integration cycle and the merge detects changes in the file in both you branches. If you as lucky the file in question is a small one like this example and you'll get a merge conflict so you can catch it right away. However real life tends to be less compliant and you'll most likely have a large file and the problem code will not lie within the same block and thus slip through with out any conflict. The resulting file would look like this:

    public class MyClass
    {
        public MyClass()
        {
        }

        public void DoWork()
        {
        }

        public void OurNeatNewBugfixMethod()
        {
        }

        public void DoMoreWork()
        {
        }

        public void OurNeatNewBugfixMethod()
        {
        }
    }


So the moral of the story is that if you need to take shortcuts in your forward / reverse integration cycles make sure that you place the code in the exact same place in both branches and you'll save your self some problems with failing builds.

If you are curious on what the heck I'm talking about when I mention forward and reverse integration check out my post on branching guidelines for TFS.

No comments:

Post a Comment