I could go with that.

I still prefer the consistency / predictability where checking out a branch will result in a consistent state (HEAD is a symref, or detached head), rather than it depending on the current state of the branch. I would expect that checking out a branch mimics `git checkout branch`, and if the caller wants to checkout a snapshot, they would call checkout with the actual branch tip commit. I guess another option is to throw an exception if the caller attempts to checkout an outdated branch, as it is ambiguous as to what they want to happen.

I will go with whichever behavior you prefer and update the documentation to make the behavior clear. I expect the vast majority of the usage will be with the branch tip corresponding to the current tip of the branch anyways.