Update (with merge)

Meanwhile, Sally is fixin’ to go ahead and add a feature that was requested by the sales team: If the user chooses the lucky number 7 as the red ball, the chances of winning are doubled. Since she is starting a new task, she decides to begin with an update to make sure she has the latest code.

lottery sally$ svn update
U    lottery.c
Updated to revision 3.

Then she implements the lucky 7 feature in two shakes of a lamb’s tail by adding just a few lines of new code to main().

lottery sally$ svn diff
Index: lottery.c
===================================================================
--- lottery.c   (revision 3)
+++ lottery.c   (working copy)
@@ -44,6 +44,11 @@
 
     int result = calculate_result(white_balls, power_ball);
 
+    if (7 == power_ball)
+    {
+        result = result * 2;
+    }
+
     printf("%d percent chance of winning\n", result);
 
     return 0;

And commits her change.

lottery sally$ svn commit -m "lucky 7"
Sending        lottery.c
Transmitting file data .
Committed revision 4.

Meanwhile, Harry has realised his last change had a bug. He modified calculate_result() to return -1 for invalid arguments but he forgot to modify the caller to handle the error. As a consequence, entering a ball number that is out of range causes the program to behave improperly.

lottery harry$ ./a.out 61 2 3 4 5 42
-1 percent chance of winning

The percent chance of winning certainly can’t be a negative number, now can it? So Harry adds an extra check for this case.

lottery harry$ svn diff
Index: lottery.c
===================================================================
--- lottery.c   (revision 3)
+++ lottery.c   (working copy)
@@ -44,6 +44,12 @@
 
     int result = calculate_result(white_balls, power_ball);
 
+    if (result < 0)
+    {
+        fprintf(stderr, "Invalid arguments\n");
+        return -1;
+    }
+
     printf("%d percent chance of winning\n", result);
 
     return 0;

And proceeds to commit the fix.

lottery harry$ svn commit -m "propagate error code"
Sending        lottery.c
Transmitting file data .svn: Commit failed (details follow):
svn: File '/lottery.c' is out of date

Blimey! Sally must have committed a new changeset already. Harry once again needs to do an update to merge Sally’s changes with his own.

lottery harry$ svn update
Conflict discovered in 'lottery.c'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: 

The merge didn’t go quite as smoothly this time. Apparently there was a conflict. Harry wonders if he could sneak out for a pint. Instead, Harry chooses the (df) option to review the conflicting changes.

lottery harry$ svn update
Conflict discovered in 'lottery.c'.
Select: (p) postpone, (df) diff-full, (e) edit,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: df
--- .svn/text-base/lottery.c.svn-base   Wed Apr  6 14:07:48 2011
+++ .svn/tmp/lottery.c.2.tmp    Wed Apr  6 19:53:26 2011
@@ -44,6 +44,20 @@
 
     int result = calculate_result(white_balls, power_ball);
 
+<<<<<<< .mine
+    if (result < 0)
+    {
+        fprintf(stderr, "Invalid arguments\n");
+        return -1;
+    }
+
+=======
+    if (7 == power_ball)
+    {
+        result = result * 2;
+    }
+
+>>>>>>> .r4
     printf("%d percent chance of winning\n", result);
 
     return 0;
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: 

Just like that. A conflict. Harry decides to (p) postpone it so he can look at the problem more carefully.

Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options: p
C    lottery.c
Updated to revision 4.
Summary of conflicts:
  Text conflicts: 1

Now he opens lottery.c in his editor to examine the situation.

...
    int result = calculate_result(white_balls, power_ball);

<<<<<<< .mine
    if (result < 0)
    {
        fprintf(stderr, "Invalid arguments\n");
        return -1;
    }

=======
    if (7 == power_ball)
    {
        result = result * 2;
    }

>>>>>>> .r4
    printf("%d percent chance of winning\n", result);

    return 0;
...

Subversion has included both Harry’s code and Sally’s code with conflict markers to delimit things. It appears that Sally’s new code can simply be included right after Harry’s error checking. So in this case, resolving the conflict is frightfully simple. Harry just removes the lines containing the conflict markers.

...
    int result = calculate_result(white_balls, power_ball);

    if (result < 0)
    {
        fprintf(stderr, "Invalid arguments\n");
        return -1;
    }

    if (7 == power_ball)
    {
        result = result * 2;
    }

    printf("%d percent chance of winning\n", result);

    return 0;
...

That should take care of the problem. Harry compiles the code to make sure and then retries the commit.

lottery harry$ svn commit -m "propagate error code"
svn: Commit failed (details follow):
svn: Aborting commit: '/Users/harry/lottery/lottery.c' remains in conflict

Crikey! Howzat? Harry fixed the conflict in lottery.c but Subversion doesn’t seem to know that.

lottery harry$ svn status
?       a.out
?       lottery.c.r3
?       lottery.c.r4
?       lottery.c.mine
C       lottery.c

Harry sees that 'C' next to lottery.c and realises that he forgot to tell Subversion that he had resolved the conflict. He uses resolve to let Subversion know that the problem has been dealt with.

lottery harry$ svn resolve --accept=working lottery.c
Resolved conflicted state of 'lottery.c'

lottery harry$ svn status
?       a.out
M       lottery.c

There, that looks much better. Harry tries the commit for the third time.

lottery harry$ svn commit -m "propagate error code"
Sending        lottery.c
Transmitting file data .
Committed revision 5.

And… Bob’s your uncle.