Update, Commit (with a merge)

Meanwhile, Harry has been coding as well. He heard somebody say that it’s best to compile with all the warnings turned on, so he decides to give it a try.

lottery harry$ gcc -std=c99 -Wall -Wextra -Werror lottery.c 
cc1: warnings being treated as errors
lottery.c:5: warning: unused parameter 'white_balls'
lottery.c:5: warning: unused parameter 'power_ball'

I say! The code has some warnings. The calculate_result() function isn’t using its parameters. Harry looks at the situation and realises the problem immediately: That function should be checking its arguments for validity! The power ball can be from 1 to 39 inclusive. The white balls can be 1 to 59 inclusive. So he implements the error checking.

int calculate_result(int white_balls[5], int power_ball)
{
    for (int i=0; i<5; i++)
    {
        if (
             (white_balls[i] < 1)
             || (white_balls[i] > 59)
           )
        {
            return -1;
        }
    }

    if (
         (power_ball < 1)
         || (power_ball > 39)
       )
    {
        return -1;
    }

    return 0;
}

Grand. Let’s see if it compiles.

lottery harry$ gcc -std=c99 -Wall -Wextra -Werror lottery.c

lottery harry$ ls -l
total 32
-rwxr-xr-x  1 harry  staff  8904 May 17 08:17 a.out
-rw-r--r--  1 harry  staff   843 May 17 08:16 lottery.c

Quite. But Harry decides to diff before committing, just for good measure.

lottery harry$ hg diff
diff -r 1f8baa59f5a4 lottery.c
--- a/lottery.c Tue May 17 07:58:36 2011 -0500
+++ b/lottery.c Tue May 17 08:17:53 2011 -0500
@@ -4,6 +4,25 @@
 
 int calculate_result(int white_balls[5], int power_ball)
 {
+    for (int i=0; i<5; i++)
+    {
+        if (
+             (white_balls[i] < 1)
+             || (white_balls[i] > 59)
+           )
+        {
+            return -1;
+        }
+    }
+
+    if (
+         (power_ball < 1)
+         || (power_ball > 39)
+       )
+    {
+        return -1;
+    }
+
     return 0;
 }

Good show. Time to commit the change.

lottery harry$ hg commit -m "fix some warnings"

No problems there. This time he remembers that he needs to push his changes to the server.

But Sally has been working at the same time and she had her change ready to commit and push first.

lottery sally$ hg commit -m "change order of the command line args to be \
                              more like what the user will expect"

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

So Harry tries to push his changes.

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)

What’s all this then? Mercurial is not allowing Harry to push his change because it would result in the default branch having two heads.

This restriction is analogous to the way the second generation tools refuse to allow a commit if it was not based on the most recent version in the repository. Mercurial allows this behavior to be overridden, but for most situations it is friendlier to the other members of the team if you do the pull and merge before you push.

Harry uses pull to bring in changes.

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)

Following the instructions from Mercurial’s output, Harry wants to see what hg heads has to say.

lottery harry$ hg heads
changeset:   2:7dd1d2434f80
tag:         tip
parent:      0:1f8baa59f5a4
user:        Sally <sally@futilisoft.com>
date:        Tue May 17 08:25:22 2011 -0500
summary:     change order of the command line args to be \
             more like what the user will expect

changeset:   1:efcd0b05ec2c
user:        Harry <harry@futilisoft.com>
date:        Tue May 17 08:24:01 2011 -0500
summary:     fix some warnings

Harry wonders why he can’t just update.

lottery harry$ hg update
abort: crosses branches (merge branches or use --check to force update)

That didn’t work. OK, maybe a merge.

lottery harry$ hg merge
merging lottery.c
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

Great! Now the merge is in the working copy.

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

Everything seems to be proper good. Harry wants to see what happened.

lottery harry$ hg diff
diff -r efcd0b05ec2c lottery.c
--- a/lottery.c Tue May 17 08:24:01 2011 -0500
+++ b/lottery.c Tue May 17 08:30:00 2011 -0500
@@ -30,16 +30,16 @@
 {
     if (argc != 7)
     {
-        fprintf(stderr, "Usage: %s power_ball (5 white balls)\n", argv[0]);
+        fprintf(stderr, "Usage: %s (5 white balls) power_ball\n", argv[0]);
         return -1;
     }
 
-    int power_ball = atoi(argv[1]);
+    int power_ball = atoi(argv[6]);
 
     int white_balls[5];
     for (int i=0; i<5; i++)
     {
-        white_balls[i] = atoi(argv[2+i]);
+        white_balls[i] = atoi(argv[1+i]);
     }
 
     int result = calculate_result(white_balls, power_ball);

Interesting. Diff shows Sally’s changes. This is because the diff was performed against changeset efcd0b05ec2c. Harry types hg parents to see the version of the tree on which his current pending changeset is based.

lottery harry$ hg parents
changeset:   1:efcd0b05ec2c
user:        Harry <harry@futilisoft.com>
date:        Tue May 17 08:24:01 2011 -0500
summary:     fix some warnings

changeset:   2:7dd1d2434f80
tag:         tip
parent:      0:1f8baa59f5a4
user:        Sally <sally@futilisoft.com>
date:        Tue May 17 08:25:22 2011 -0500
summary:     change order of the command line args to be \
             more like what the user will expect

Because it is a merge in progress, his working copy has two parents. The resulting DAG node will have two parents as well.

His code is already committed. Apparently Mercurial was able to merge Sally’s changes directly into Harry’s modified copy of the file without any conflicts. Smashing! Let’s see if it compiles.

lottery harry$ gcc -std=c99 -Wall -Wextra -Werror lottery.c

lottery harry$ ls -l
total 32
-rwxr-xr-x  1 harry  staff  8904 May 17 08:34 a.out
-rw-r--r--  1 harry  staff   843 May 17 08:28 lottery.c

Very well then. So Harry is ready to commit the merge.

lottery harry$ hg commit -m "merge"

And now hg parents shows only one node but that node has two parents.

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

And 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