Many thanks to @VonC for suggesting the use of the merge=custom-driver attribute in the .gitattributes file. While this will work, I'm reluctant to pollute my workspace with .git files, and while I could use $GIT_DIR/info/attributes to avoid the pollution, I'm bothered by the need for 2 rules to catch dot-files and non-dot files.
After a bit of experimentation I managed to get a solution with the merge.default configuration variable (mentioned in the gitattributes(5) manpage) working. The trick I missed was that merge.default takes the name of a custom driver you have defined previously; you don't give it the custom command directly. Here's what works for me...
First define your copy-merge custom driver. You can use shell commands directly; there's no need for an external script (just make sure you get your shell meta-character quoting right):
git config merge.copy-merge.name 'Copy Merge'
git config merge.copy-merge.driver 'mv %B %A'
Note that mv returns 0 on success, 1 on failure, meeting the criteria for reporting merge "success" back to git.
Now tell git that ALL merges are copy-merges:
git config merge.default copy-merge
Hey Presto! Job done. git merge <branch> will now copy-merge everything so the branch you're on contains exact copies of all files on <branch>. QED.
If you want to do a non-copy-merge then simply reset the default merge driver:
git config --unset merge.default
If you do want to be more selective then leave merge.default unset and use attributes as @VonC says:
cd path/to/copy-merge/in
echo '* merge=copy-merge' > .gitattributes
echo '.* merge=copy-merge' >> .gitattributes
Do this at the top of every subtree you want to copy-merge in. If there's a sub-subtree that you DON'T want to copy-merge in, you can turn it off again:
cd path/to/copy-merge/in/path/to/normal-merge/in
echo '* merge' > .gitattributes
echo '.* merge' >> .gitattributes
WARNING: littering your working tree with lots of .gitattributes files is bound to lead to confusion, especially if you also use things like "*.bin -merge" in other directories to force all merges of .bin files to fail with conflicts. It may be better to use $GIT_DIR/info/attributes for this sort of thing, as it has the highest precedence.