6

Preface: this is not a general question about merge conflicts, but a very specific case that keeps bugging me. It is quite trivial, but it does amount to a (slight) hassle often enough to stand out. I am not concerned about general merging, this is just about saving a few seconds here and there for very mechanical conflict resolution, by avoiding said conflict in the first place. I am also absolutely aware that this is not a "git problem" or something like that.

That said, assume we have a source file of a class:

class Xyz
    ...
    ...
   def last_method
      ...
   end
end

This starts out identical in master and several feature branches. Now, as we implement our features, we add more methods to this class:

Branch 1:

class Xyz
    ...
    ...
    def last_method
        ...
    end

    def new_method1
        ...
    end
end

Branch 2:

class Xyz
    ...
    ...
    def last_method
        ...
    end

    def new_method2
        ...
    end
end

The new methods are not related and will happily coexist when both branches are merged back to master.

Obviously this will lead to a merge conflict. The reason is clear - we changed the source file at exactly the same spot, and obviously git cannot (and should not) magically decide for us that this is not a "real" conflict; git would have to chose which of the methods should be placed first, etc.

One way to avoid the conflict would be to insert the new methods at different places in the file (assuming the order does not matter), but we really don't want to spend much effort (or any at all, actually) to mentally keep track where to insert stuff or what happens in other features.

The question, then: is there another way, maybe some coding convention, that you are regularly applying, which somehow avoids this merge conflict?

jub0bs
  • 60,866
  • 25
  • 183
  • 186
AnoE
  • 8,048
  • 1
  • 21
  • 36

1 Answers1

2

This is a good question. However, there are ways of mitigating the problem, under certain conditions.

In the ideal case, at the time of designing a class, you decide what it's going to be made of (variables, methods, etc.), and you can already choose appropriate names for those. In that case, you should write stubs of those methods in the commit that introduces the class.

Those stubs will then act as "anchors" for a line-based version control system such as Git:

class MyClass

    def initialize
        # TODO
    end

    def get_ID
        # TODO
    end

    def set_ID
        # TODO
    end
end

After this "first" commit, different contributors are free to change the body of different methods: in my example, Alice can implement get_ID and Bob can implement set_ID without fear of running into a merge conflict further down the road, because the def and end lines of each method are already present in the original commit.

jub0bs
  • 60,866
  • 25
  • 183
  • 186
  • Thanks for your answer, and I appreciate that you mentioned "under certain conditions". Those unfortunately don't apply - in my case it's agile/BDD driven development where we are doing quite the opposite; i.e., we do not have unused placeholder code or even "todo" implementations of empty methods (at least not in `master`). – AnoE Aug 14 '15 at 14:40
  • @Ekkehard That's all I can think of. It's easy, as a human being, to see that different methods added by different contributors shouldn't cause a merge conflict, but from the diff3 algorithm is not sophisticated enough to detect that; as far as it's concerned, different lines added at the same location => conflict. – jub0bs Aug 15 '15 at 16:56