FreeBSD's development model requires that (unless it's an exceptional circumstance) changes first go in to the HEAD. If they are suitable candidates to go in to stable then they should be merged to the relevant stable branch.
In addition, new features may first be developed on a separate branch, before being merged in to the HEAD.
The VCS should support easy merging of changes from HEAD (or its equivalent) to the stable branches, and from feature branches to HEAD. Merges should also be able to go both ways, and be easily repeatable (e.g., a long lived feature branch may merge changes from HEAD on to the branch several times, and may merge changes from the branch back to HEAD several times)
Subversion supports merging changes between revisions, and placing the merged results in arbitrary parts of the repo (or working copy), using the "svn merge" command.
What Subversion does not (currently) do is remember which revisions have been merged where. This requires you to maintain this information separately. If you do not, repeated merges (e.g., from the trunk to a branch) will generate conflicts.
This information can either be maintained outside the repository, inside the repository as metadata in a commit message (in much the same way as we use commit messages for metadata like "MFC After", or "Approved by" today, or inside the repository using properties. Properties are arbitrary key/value pairs that can be attached to paths and/or revisions in the repository.
A third party tool called "svnmerge" (ships in the Subversion distribution) takes this third approach. A detailed write up showing how it could be used with FreeBSD is at SVN_Merging.
Hg does support merging between branches of course and being changeset-based, it is very efficient, sending only the changesets not already present in the target repository.
When merging, the changesets are merged first in a temporary head or internal branch in the repository. Then, it is merged with the working directory data either automatically (through hg pull -u) or manually (with hg update or hg merge).
That is done this way to reduce potental conflicts because upstream code is less likely to generate conflicts than local modifications.
You can also have multiples heads within an Hg repo without merging and it could be used for internal branches without going through a complete clone.
Supported (also see monotone:FeatureMerging)
Monotone has very robust and powerful merging capabilities, which work based on the DAG history structure, independent of branches. These capabilities work regardless of how developers choose to use branches.
The merge, propagate and explicit_merge commands all access the same underlying merging capabilities, and differ only in how they select the revisions to be merged. merge picks multiple heads of the same branch, propagate merges the changes along one branch into another, and explicit_merge lets you pick whatever you like.
A very common developer loop:
<edit files> $ mtn commit $ mtn pull <new revisions incoming> $ mtn merge $ mtn sync <local commits and merge node(s) outgoing, maybe more revisions incoming> $ mtn update