复杂的Git分支名称破坏了所有Git命令

rui*_*eco 337 git zsh parentheses git-branch

我试图master用以下命令创建一个分支,

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery
Run Code Online (Sandbox Code Playgroud)

当Git突然停止响应时.我怀疑未经证实的人()不应该受到责备.现在,每当我尝试运行任何Git命令时,我都会收到同样的错误:

git:176: command not found: _of_ProductSearchQuery
Run Code Online (Sandbox Code Playgroud)

git每次输入命令后增加的数字.

谁能解释发生了什么?我该如何恢复正常?我想删除那个分支,但我该怎么做呢?

jub*_*0bs 616

问题

谁能解释发生了什么?[...]我希望能够删除那个分支,但Git不适合我.

通过运行

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery
Run Code Online (Sandbox Code Playgroud)

在zsh中,您没有创建任何分支.相反,你意外地定义了三个shell函数,称为git,branchSSLOC-201_Implement___str__,它们忽略了它们的参数(如果有的话)和它们的主体_of_ProductSearchQuery.您可以通过调用名为builtin zsh的命令来检查自己确实发生了这种情况,该命令functions列出了所有现有的shell函数:

$ functions                                                     
SSLOC-201_Implement___str__ () {
    _of_ProductSearchQuery
}
branch () {
    _of_ProductSearchQuery
}
git () {
    _of_ProductSearchQuery
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,虽然其他两个shell函数没有问题,但是名为"git"的shell函数现在会影响真正的 git命令!

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

因此,您将随后收到错误

command not found: _of_ProductSearchQuery
Run Code Online (Sandbox Code Playgroud)

每当你试图运行Git命令时,例如git log,git status等等(当然,假设没有调用命令_of_ProductSearchQuery存在).

边注

[...] 我犯了同样的错误:

git:176: command not found: _of_ProductSearchQuery
Run Code Online (Sandbox Code Playgroud)

(git每次输入命令后增加的数字)

该数字只对应于HISTCMD一个环境变量的值

[t]交互式shell中的当前历史事件编号,换句话说,是导致$HISTCMD读取的命令的事件编号.

有关详细信息,请参阅zsh手册.

我该如何恢复正常?

只需删除有问题的shell函数(以及你偶然创建的其他两个函数,当你在它时):

unset -f git
unset -f branch SSLOC-201_Implement___str__
Run Code Online (Sandbox Code Playgroud)

那一切都应该没问题.

如果unset被遮蔽也会怎么样?!

好问题!我推荐你下面的Wumpus W. Wumbley的优秀评论.


分支命名技巧

避免任何特殊的shell字符

是的,正如评论中所指出的,括号是Git分支名称中的有效字符; 你只需要恰当地引用这个名字,例如

$ git branch 'foo()bar'
$ git branch
  foo()bar
* master
$ git checkout 'foo()bar'
Switched to branch 'foo()bar'
Run Code Online (Sandbox Code Playgroud)

但是,当用作命令行参数时,每次引用此类名称的需要应该说服您避免使用引用名称中的括号.更一般地说,你应该(尽可能地)避免在shell中具有特殊含义的字符,以防止像这样的意外.

使用简单的分支名称

无论如何,你应该保持你的分支名称简短而甜蜜.很长的描述就像

SSLOC-201_Implement ___ STR __()_ of_ProductSearchQuery

属于提交消息,而不是分支名称.

  • 你可以使用`builtin unset`.如果`builtin`和`unset`都被函数遮蔽了,那么`unfunction`.如果那也是,'unhash -f`.如果所有这四个都消失了,那么*然后*重新启动shell. (45认同)
  • 如果有人通过创建所谓的shell函数来影响`unset`会发生什么?(这可能吗?) (12认同)
  • 该线程中没有任何内容表明parens是非法的.Git似乎很喜欢它."切换到新的分支"abcd - () - foo'` (4认同)
  • @codroipo哈!那是个很好的观点.是的,这是可能的,在这种情况下,你可能最好重新启动`zsh`. (2认同)