That said, CLAs usually include protections that permissive licenses don't. For example, CLAs often require the contributor to guarantee they have the rights to license their contributions, and didn't lift code from someone else without proper permission. Anecdotally, CLAs are also just better licenses, in terms of legal implementation. Especially when it comes to patent rights, though no license can completely eliminate patent risk.
I do this, and contributors are fine with it. Commercial licensees don't mind complying with a combined commercial + BSD/MIT license.
All the code is GPL. The contributions are dual licensed to the maintainer as GPL+MIT, which means that the maintainer can relicense them as they please, just like the code they own the copyright for. So other than minor formalities like maintaining a list of copyright owners, the maintainer can continue to release both GPL and commercial versions unimpeded. Keeping track of which lines were contributed in this way going forward isn't really necessary (although a note in the merge commit would be prudent).
The main practical difference between a CLA and actual copyright assignment is when you are suing a violator. At that point it is a bit simpler if there is one copyright owner, rather than asking other copyright owners to join the suit, but it is important to realize that they don't have to join the suit for it to go forward (in fact, every copyright owner could sue the violator independently if they wish). Only when you are the copyright owner of a minority of the software's source code (IOW most of the source comes from contributions) do things get inconvenient in terms of a violator possibly being less motivated to negotiate with you (although that would actually be really stupid on their part).
One thing I wanted to try, but never really got to, was to ask contributors to license additions to a GPL project under the MIT license. These can be shipped under the proprietary license. As long as the original authors continue to do a large part of the work, most code remains GPL preventing proprietary forks and safeguarding your proprietary revenue model.
[edit: clarity]