tags:

views:

149

answers:

2

Hi

I'm trying to understand the details of the subversion merge commands. I think understanding the difference between a change that is also a conflict and a change that is not a conflict would help.

This is a followup to this thread.

Thanks!

+4  A: 

Consider a function like this (call it revision 1)

void foo(){
    int bar;
}

Now let's suppose two people make changes to this function, both starting from revision 1.

Alice:

void foo(){
    char bar;
}

Bob:

double foo(){
    double bar;
    bar = 0;
    return bar;
}

For the sake of this example, let's suppose Alice commits her changes.

Now Bob goes to commit changes, and svn will tell Bob he's out of date, and needs to update and merge changes. So Bob runs an update, and the merge occurs.

Basically, it's (somewhat) easy to see that what happens is an analysis that decides what Bob changed from revision 1 and what Alice changed from revision 1. A simple merge will produce something like

double foo(){
    [conflict] bar;
    bar = 0;
    return bar;
}

Note that both Alice and Bob changed the type of bar from int, except Alice made it char and Bob made it double. The merger cannot decide which one is correct (it's not doing code analysis), so as a human Bob needs to help resolve the conflict.

The example is, of course, somewhat contrived, and with the exception of the noted conflict, all other changes are not conflicts.

If Bob had not changed the type of bar, the files would've merged without conflict.

Mark E
Nice example. +1
Simon P Stevens
+9  A: 

A change that is a conflict is when 2 people have both made a change to the same file in such a way that the two changes can not be automatically resolved.

1) Lets start with an example of a non-conflicting merge.

Original file

line1
line2
line3

Person A changes it to this:

line1CHANGED
line2
line3

Person B changes it to this:

line1
line2CHANGED
line3

When those are both checked in and merged, there is no conflict because it can easily resolve to produce this final file:

line1CHANGED
line2CHANGED
line3

Subversion will handle this automatically as a merge.

2) Now an example of conflicting changes.

Original file

line1
line2
line3

Person A changes it to this:

line1CHANGED_BY_A
line2
line3

Person B changes it to this:

line1CHANGED_BY_B
line2
line3

This can't be merged automatically, so it is a conflict. You will need to resolve, either by accepting person A's change or person B's change. In this case subversion will warn you of conflicts and require a decision from you on how to resolve them.

3) Finally, you can have both conflicting and non conflicting changes within the same revision.

Original file

line1
line2
line3

Person A changes it to this:

line1CHANGED_BY_A
line2ALSO_CHANGED_BY_A
line3

Person B changes it to this:

line1CHANGED_BY_B
line2
line3ALSO_CHANGED_BY_B

Now, with this example, both people have changed the file, and there is a conflicting change on line 1 that must be resolved, but lines 2 & 3 are non-conflicting changes and can be resolved automatically.

You can choose to resolve this in several ways.

Firstly, you can fully accept either A's or B's file and discard the other. This would result in the other persons non-conflicting changes being lost. Say, you choose to fully resolve using A, your final file would be:

line1CHANGED_BY_A
line2ALSO_CHANGED_BY_A
line3

(Exactly A's file, and all changes by B are discarded)

Secondly, you can resolve only the conflicting changes, and still retain all the non-conflicting changes. This was you would choose either A's or B's change for the first line, and still get both of the other line's changes, from both people. So, say for example you choose to resolve conflicts using A, your final file would be:

line1CHANGED_BY_A
line2ALSO_CHANGED_BY_A
line3ALSO_CHANGED_BY_B

Alternative you can use tools like KDiff that support reviewing of each conflict separately (because of course you can have mutliple changes, both conflicting and non-conflicting, within the same file), which will allow you to select different methods of resolution for each.

If you are having trouble understanding merging with the command line tools I strongly recommend you take a look at KDiff (or some other GUI merge/diff tool) as they display the files alongside each other (along with the original) and allow you to visual what each resolution action would do.

Simon P Stevens
Thank you for your detailed answer! I was able to reproduce your examples in a svn project and I finally understand the difference between the mine-conflict and mine-full commands! =)
Hua-Ying