It does not let you merge if you have uncommitted work, just like git:
$ hg pull
pulling from ...
requesting all changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)
$ hg update
abort: crosses branches (use 'hg merge' to merge or use 'hg update -C' to discard changes)
$ hg merge
abort: outstanding uncommitted changes (use 'hg status' to list changes)
Sorry, you're right that it does refuse to merge with the working copy if the changeset you're updating to is not a direct descendent of the changeset you're currently at (this is what the error about "crosses branches" refers to).
However, if it is a direct descendent, it will try to merge for you:
$ echo b >> a
$ hg status
M a
$ hg pull ../a
pulling from ../a
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
(run 'hg update' to get a working copy)
$ hg update
merging a
warning: conflicts during merge.
merging a failed!
0 files updated, 0 files merged, 0 files removed, 1 files unresolved
use 'hg resolve' to retry unresolved file merges
$ hg resolve -l
U a
In this example, the upstream repository made a change to "a" that conflicts with my local, uncommitted change to the same file. It uses its normal merge machinery to try to resolve the conflict.
As far as I know, Git doesn't allow merges in this situation.