Handling if's with parenthesis
Giorgos Keramidas
keramida at ceid.upatras.gr
Fri Dec 5 15:06:31 UTC 2008
On Fri, 5 Dec 2008 15:24:51 +0200, "E.L.K." <some.any.key at gmail.com> wrote:
> Hello all!
>
> My question is:
> For example, I have a file like this:
>
> int main(){
> if (true){
> somefunc();
> }
> }
>
> It is checked in to mercurial repository. Then, two people clone this
> repo and make next changes:
>
> 1. Remove parenthesis over if's block, so result looks like:
> int main(){
> if (true)
> somefunc();
> }
>
> 2. Adds second function call to if's block, so result looks like:
>
> int main(){
> if (true){
> somefunc();
> somefunc2();
> }
> }
>
> Then first makes push, all ok. Then second makes pull, merge (merge
> done automatic) and push. Now we have next contents of this file:
>
> int main(){
> if (true)
> somefunc();
> somefunc2();
> }
>
> Which is clearly not what was intended.
This is a merge problem of the developer who merged the two heads. The
person who merged the two heads did not really do a sensible merge of
the two code blocks.
If I re-create the example merge here, with a history like this:
: keramida at kobe:/tmp/hgtest$ hg manifest
: hello.c
: keramida at kobe:/tmp/hgtest$ hg glog
: @ 2[tip]:0 772af6164141 2008-12-05 16:53 +0200 keramida
: | add extra function call
: |
: | o 1 894862a0a70b 2008-12-05 16:53 +0200 keramida
: |/ remove unnecessary braces
: |
: o 0 2465815a51b3 2008-12-05 16:53 +0200 keramida
: add hello.c
:
: keramida at kobe:/tmp/hgtest$
Then ediff-mode of GNU Emacs, running as a 3-way merge tool, shows three
buffer windows that clearly mark (with colors) the following regions as
parts of the file that include changes:
+-------------------------+ +-------------------------+
|int main() { | |int main() { |
=> | if (true) | => | if (true) { |
| somefunc(); | | somefunc(); |
=> |} | => | somefunc2(); |
| | => | } |
| | |} |
+-------------------------+ +-------------------------+
The conflict resolution area may be a bit confusing in this case,
because it shows:
+---------------------------------------------------------+
|int main() { |
=> | if (true) |
| somefunc(); |
=> |<<<<<<< variant A |
=> |>>>>>>> variant B |
=> | somefunc2(); |
=> | } |
=> |####### Ancestor |
=> | } |
=> |======= end |
|} |
+---------------------------------------------------------+
The only indication that there may be something `odd' about the ``if
(true)'' part is that is is highlighted by a different colour, but there
is *still* a choice of which variant to pick for every little hunk of
changes.
A good merge tool can do that for you. It can point out that something
needs more attention. But it can't really do anything `sensible' on a
_semantic_ level. That's the job of the human who does the merge and
checks the merge results.
What you just noticed as a bad human choice during a merge is a bit easy
to hit. This is why it is _always_ a good idea to look at the merge
diff *after* the merge and check that everything looks sane :)
More information about the Mercurial
mailing list