by Valentin, February 11 2018, in tech

Git branches and slashes

I've found out that using slashes to name git branches in a hierarchy fashion is limited to only one level:

$ git checkout -b feature/public-api
Switched to a new branch 'feature/public-api'
$ git checkout -b feature/public-api/oauth2
fatal: cannot lock ref 'refs/heads/feature/public-api/oauth2': 'refs/heads/feature/public-api' exists; cannot create 'refs/heads/feature/public-api/oauth2'

The reason for this is that a git branch is simply a text file in the .git/branches directory, containing the hash of the commit at the tip of the branch. When a branch's name contains a slash, git creates a subdirectory to store this file in. So the hash of the branch feature/public-api is stored at .git/branches/feature/public-api. If you try to add one more level to that, then git will try to create the .git/branches/feature/public-api directory, which is impossible, because there's already a file with this name.

It's yet another leaky abstraction from git, once again for the purposes of performance and simplicity of implementation, which I can understand.