Complex Git branch name broke all Git commands Complex Git branch name broke all Git commands git git

Complex Git branch name broke all Git commands


Problem

Can anyone explain what happened? [...] I'd love to be able to delete that branch, but Git won't work for me.

By running

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

in zsh, you did not create any branch. Instead, you accidentally defined three shell functions, called git, branch, and SSLOC-201_Implement___str__, which ignore their parameters (if any) and whose body is _of_ProductSearchQuery. You can check for yourself that this is indeed what happened, by invoking the builtin zsh command called functions, which lists all existing shell functions:

$ functions                                                     SSLOC-201_Implement___str__ () {    _of_ProductSearchQuery}branch () {    _of_ProductSearchQuery}git () {    _of_ProductSearchQuery}

Unfortunately, although the other two shell functions are not problematic, the shell function called "git" now shadows the bona fide git command!

$ which gitgit () {    _of_ProductSearchQuery}# but the real "git" is a binary file that lives in /usr/local/bin/git (or some similar path)

Therefore, you will subsequently get the error

command not found: _of_ProductSearchQuery

whenever you attempt to run a Git command, e.g. git log, git status, etc. (assuming, of course, that no command called _of_ProductSearchQuery exists).

Side note

[...] I get the same error:

git:176: command not found: _of_ProductSearchQuery

(with the number after git increasing every time I type a command)

That number simply corresponds to the value of HISTCMD, an environment variable that holds

[t]he current history event number in an interactive shell, in other words the event number for the command that caused $HISTCMD to be read.

See the zsh manual for more details.

Solution

And how do I get back to normal?

Simply delete the problematic shell function (and the other two you created by accident, while you're at it):

unset -f gitunset -f branch SSLOC-201_Implement___str__

Then everything should be fine.

What if unset is shadowed also?!

Good question! I refer you to Wumpus W. Wumbley's excellent comment below.


Branch-naming tips

Avoid any special shell characters

Yes, as pointed out in the comments, parentheses are valid characters in Git branch names; you just need to quote the name appropriately, e.g.

$ git branch 'foo()bar'$ git branch  foo()bar* master$ git checkout 'foo()bar'Switched to branch 'foo()bar'

However, the need for quoting such names every single time when used as command-line arguments should convince you to eschew parentheses in reference names. More generally, you should (as much as possible) avoid characters that have a special meaning in shells, to prevent surprises like this one.

Use simple branch names

You should keep your branch names short and sweet anyway. Long descriptions like

SSLOC-201_Implement___str__()_of_ProductSearchQuery

belong in commit messages, not in branch names.