Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Practical guide to Subversion branch merging

Preface

I realise there are already a lot of questions about merging SVN branches on Stack Overflow. I have read many of them, but still haven't really found the information I'm looking for, so please read this question in it's entirety before proposing to close it as a duplicate.


I need to merge one SVN branch into another. I'm pretty comfortable with the theory of branching and merging, but I've always struggled with the practice of performing the merge, more specifically, with identifying and resolving conflicts. I suspect the root cause of this problem is a lack of understanding on my part of the tools required to get the job done, that is, TortoiseSVN and the various visual merging tools that are available.

Based on reading various related Stack Overflow questions, I've identified Sourcegear DiffMerge and Beyond Compare as candidate tools for performing the three-way merge. I tried DiffMerge, but struggled to use it effectively. I expected to see the following three files while resolving conflicts

  • File from branch A
  • File from branch B
  • Result of performing the merge

But instead what I see is

  • File from branch A
  • File from branch B
  • Common ancestor of A and B, AKA base revision

This led me to wonder how I can see the result of the merge after each action I take when resolving conflicts visually. I also struggled to actually perform such action, for example, accepting a particular change from either branch A or B. After reading about the subject a bit more, it now seems that the base revision is in fact the place where the results of the merge should be shown, is that correct?

I think a screencast or video tutorial that demonstrates merging branches with TortoiseSVN and a visual merge tool would probably answer most of my outstanding questions about how to use these tools effectively. I'm more interested in the process of resolving conflicts that performing the merge itself, but it would be great if both were covered.

like image 695
Dónal Avatar asked Dec 18 '09 04:12

Dónal


2 Answers

Actually, there are two-way and three-way merging tools. A two-way should show three windows. The source branch version A, the target branch version B and a result of the merge. A three-way merge will show the base version in addition to that. You can imagine a three way merge sort of as equation of Result = Target + ( Base - Source ). In effect the algorithm will compute set of diffs between base and source and another set between base and target, then strike out all the diffs common to both. Then it will show you a list of remaining diffs for decision. For diffs in either source or target where the same section of code is not affected in the other branch, it will automatically pre-decide to use the appropriate diff. Where the diffs are in same section of code in both branches, the diffs are marked as a conflict and your tool will usually walk you through conflicts one by one. Conflicts are not pre-decided and the code will not appear in result file until you make a decision. You get option to skip to next diff or to next conflict. All conflicts must be decided by you. Based on your knowledge sometimes you want to roll back (re-decide) even non-conflicting diff in order to complete the merge.

So the process of merging a file is basically walking down through diffs or to speed up only through conflicting diffs one by one and deciding whether to take source branch change, target branch change or to edit the code in question to create a new merged change. The changes you do should appear in the result window and once you decide all conflicts, the tool should allow you to save the result, which will then become a new version on the target branch. The window with base file is usually shown only for a reference as a version that has neither a source or target change.

Some tools allow for so called automatic merge. In case there are no conflicting diffs, the tool will use the pre-decided diff resolution without asking you any questions. Esentially taking all changes from both source and target branch automatically. While lexically those changes do not conflict, they might still conflict in other ways. The resulting code might not compile or be logically correct. But no merge tool can decide that. That is why merge results should be read and reviewed by a human and then compiled and run through a test suite before being committed to the target branch.

like image 54
Jiri Klouda Avatar answered Oct 02 '22 14:10

Jiri Klouda


You can install KDiff3 to perform a three-way merge with TortoiseSVN. It automatically integrates with TortoiseSVN on the Windows platform.

The three files it shows you are common ancestor of both branches, file from branch A and file from branch B. You then resolve the conflicts into the file that represents the branch that you are merging TO.

I find that it is a very intelligent tool, and will in normal cases automatically choose the correct option for merging simple conflicts.

When it is not sure, it will ask you what to do.

I have on occasion had issues where it chose the wrong way around. Those were occasions where the branch/merge path were quite complex though.

And, as GrayWizard said, sometimes it is easier to look at the raw file. Subversion will product a single raw file in the branch that you are merging to with markup in showing you which changes were from which revision. I have once or twice needed to open that file in my IDE and fix it from there.

like image 40
Joon Avatar answered Oct 02 '22 14:10

Joon