Complex Git branch name broke all Git commands
I was trying to create a branch from master
with the following command,
git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery
when Git suddenly stopped responding. I suspect the unescaped ()
are to blame, somehow. Now, whenever I try to run any Git command, I get the same error:
git:176: command not found: _of_ProductSearchQuery
with the number after git
increasing every time I type a command.
Can anyone explain what happened? And how do I get back to normal? I'd like to delete that branch, but how can I do that?
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 git
git () {
_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 git
unset -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.