You simply commit a new changeset based on the desired parent. The branch would be created implicitly by having a revision with two or more children. It does not have to carry a name; naming revisions (or sets of revisions) is an orthogonal concept for the purpose of navigating the revision DAG [1], whereas in Git branches have the additional purpose of keeping revisions from being GCed. Any revision that is not referenced by a ref (directly or indirectly) will eventually be GCed (once it is removed from the reflog and the grace period has expired).
> It doesn't make sense to me that they're a byproduct of having a garbage collector
It is a byproduct. Because if you did the above in Git (which Git won't let you without being explicit about it, but it's possible), then one or the other child would get GCed sooner or later. That's because there's only one HEAD commit, and that can prevent only one child from being GCed, so you have to create a ref to the other (generally via a branch) to keep it alive.
> since (1) git-stash exists [...] and (3) git-clean honestly seems tacked on rather than a core piece of the design.
This has nothing to do with git stash or git clean. I'm talking about one of Git's architectural principles, where the repository is essentially a purely [2] functional data structure and revisions that are not reachable from one of the roots (refs/branches) are subject to garbage collection.
[1] And if you look (aside from Mercurial) at Bazaar, Fossil, Monotone, or Veracity, you'll find that there are multiple ways to go about that.
[2] Well, not entirely pure, but close enough.