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.