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 a pull and update to make sure she has the latest code.

lottery sally$ hg pull
pulling from http://server.futilisoft.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
(run 'hg update' to get a working copy)

lottery sally$ hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

lottery sally$ hg parents
changeset:   3:edbf336fe3fa
tag:         tip
parent:      2:efcd0b05ec2c
parent:      1:7dd1d2434f80
user:        Harry <harry@futilisoft.com>
date:        Tue May 17 08:35:28 2011 -0500
summary:     merge

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$ hg diff
diff -r edbf336fe3fa lottery.c
--- a/lottery.c Tue May 17 08:35:28 2011 -0500
+++ b/lottery.c Tue May 17 08:45:34 2011 -0500
@@ -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. And pushes it too.

lottery sally$ hg commit -m "lucky 7"

lottery sally$ hg push
pushing to http://server.futilisoft.com:8000/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files

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$ hg diff
diff -r edbf336fe3fa lottery.c
--- a/lottery.c Tue May 17 08:35:28 2011 -0500
+++ b/lottery.c Tue May 17 10:15:19 2011 -0500
@@ -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 and push the fix.

lottery harry$ hg commit -m "propagate error code"

lottery harry$ hg push   
pushing to http://server.futilisoft.com:8000/
searching for changes
abort: push creates new remote heads on branch 'default'!
(you should pull and merge or use push -f to force)

Blimey! Sally must have pushed a new changeset already. Harry once again needs to pull and merge to combine Sally’s changes with his own.

lottery harry$ hg pull
pulling from http://server.futilisoft.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
lottery harry$ hg merge
merging lottery.c
warning: conflicts during merge.
merging lottery.c failed!
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon

The merge didn’t go quite as smoothly this time. Harry wonders if anyone would notice if he were to leg it down to the pub. Apparently there was a conflict. Harry decides to open up lottery.c in his editor to examine the situation.

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

<<<<<<< local
    if (result < 0)
=======
    if (7 == power_ball)
>>>>>>> other
    {
<<<<<<< local
        fprintf(stderr, "Invalid arguments\n");
        return -1;
=======
        result = result * 2;
>>>>>>> other
    }

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

    return 0;
...

Mercurial has included both Harry’s code and Sally’s code with conflict markers to delimit things. What we want is to include both blocks of code. Sally’s new code can simply be included right after Harry’s error checking.

...
    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 commits the merge.

lottery harry$ hg commit -m "merge"
abort: unresolved merge conflicts (see hg resolve)

Crikey! Now what? Harry fixed the conflict in lottery.c but Mercurial doesn’t seem to know that. The output suggested hg resolve.

lottery harry$ hg resolve -l
U lottery.c

Ah yes. Harry realises that he forgot to tell Mercurial that he had resolved the conflict. He uses resolve to let Mercurial know that the problem has been dealt with.

lottery harry$ hg resolve -m lottery.c

lottery harry$ hg resolve -l
R lottery.c

There, that looks much better. Harry tries again to commit the merge.

lottery harry$ hg commit -m "merge"

And then to retry the push.

lottery harry$ hg push
pushing to http://server.futilisoft.com:8000/
searching for changes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 2 changesets with 2 changes to 1 files

And… that’s the last wicket.