The trick is that `test` and even `[` (which is essentially another name for `test`) are ordinary commands, that exist as stand-alone binaries as well as identical-behaving built-ins. They masquerade as syntax, but they're really not. You can even call them from other, non-shell languages:
>>> from subprocess import run
>>> run(('/usr/bin/[', '-n', '', ']'))
CompletedProcess(args=('/usr/bin/[', '-n', '', ']'), returncode=1)
>>> run(('/usr/bin/test', '3', '=', '3'))
CompletedProcess(args=('/usr/bin/test', '3', '=', '3'), returncode=0)
That means that they're not allowed to do anything to variables, because the variables are inside the shell. `test` doesn't see `"$git_branch"`, it only sees the content of the variable.Per the normal rules, `"$git_branch"` is an empty string iff $git_branch is empty or unset. Leaving the quotes off can do unexpected things, though a lot less so in fish. Using single quotes means you get a literal string, without any substitution.
You're just looking for an empty string anyway, so you might as well use the equality operator instead of digging through the 18 (!) unary flags prescribed by POSIX. So I'd write either `[ "$git_branch" = "" ]` or `test "$git_branch" = ""`. Some implementations support `==` as another way to write `=`, but `=` is standard.
This modularity makes the shell simpler, but it's not exactly sane. I think that providing `[` was a mistake, because it doesn't look like a command, but maybe having `test` as a command is better than having special expression syntax just for these cases.