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


338

我试图master使用以下命令从中创建分支,

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

当Git突然停止响应时。我怀疑未逃脱()的罪魁祸首。现在,每当我尝试运行任何Git命令时,都会出现相同的错误:

git:176: command not found: _of_ProductSearchQuery

git每次输入命令后数字都会增加。

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


8
我猜想这与您的zsh环境有关,因为我能够在bash shell中运行创建分支而没有不良副作用(lubuntu 13.10),但是当我切换到完全香草的zsh时看到了错误
Jonathan.Brink

27
将来,请引用看起来可疑的内容。git branch "SSLOC-201_Implement___str__()_of_ProductSearchQuery"效果很好。
Qix-蒙尼卡(Monica)

11
@Qix最好完全避免出现有问题的字符。
jub0bs

3
@Jubobs绝对可以,尽管我已经看到某些公司强制使用这种奇怪的分支机构名称。
Qix-蒙尼卡(Monica)

1
@DwightSpencer您的链接特定于Bash,但此问题特定于zsh。该问题实际上并未在Bash中发生。
jub0bs 2015年

Answers:


617

问题

谁能解释发生了什么事?[...]我很想能够删除该分支,但是Git不能为我工作。

通过运行

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

在zsh中,您没有创建任何branch。而是,您意外地定义了三个壳函数,分别称为gitbranchSSLOC-201_Implement___str__,而忽略了它们的参数(如果有),其主体为_of_ProductSearchQuery。您可以通过调用名为z的内置zsh命令来检查自己是否确实发生了这种情况,该命令functions列出了所有现有的shell函数:

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

不幸的是,尽管其他两个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)

因此,您随后将收到错误

command not found: _of_ProductSearchQuery

每当您尝试运行Git命令(例如git loggit status等)时(当然,假设不_of_ProductSearchQuery存在任何调用的命令)。

边注

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

git:176: command not found: _of_ProductSearchQuery

(随着git我每次键入命令后数字的增加)

该数字仅对应于的值HISTCMD,该环境变量包含

交互式外壳中的当前历史事件编号,即导致$HISTCMD读取的命令的事件编号。

有关更多详细信息,请参见zsh手册

我如何恢复正常?

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

unset -f git
unset -f branch SSLOC-201_Implement___str__

然后,一切都会好起来的。

如果unset还被阴影遮住了怎么办?

好问题!我向您推荐Wumpus W. Wumbley在下面的出色评论


分支命名技巧

避免使用任何特殊的外壳字符

是的,正如评论中指出的那样,括号是Git分支名称中的有效字符;您只需要适当地引用名称,例如

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

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

使用简单的分支名称

无论如何,您应该使分支名称简短而可爱。详细说明如

SSLOC-201_Implement ___ str __()_ of_ProductSearchQuery

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


4
该线程状态中的任何内容均禁止非法。Git似乎很好。Switched to a new branch 'abcd-()-foo'
Qix-蒙尼卡(Monica)

1
看起来不错; 使用它们绝对不是一个好主意,但是从技术上讲它们并不是无效的。
Qix-蒙尼卡(Monica)

12
如果有人也unset通过创建所谓的shell函数来隐藏阴影,会发生什么?(这可能吗?)
Matteo Umili

2
@codroipo哈!那是个很好的观点。是的,有可能,在这种情况下,最好重新启动zsh
jub0bs 2015年

45
您可以使用builtin unset。如果builtinunset都已被函数遮盖,则unfunction。如果那是没了,unhash -f。如果这些全部四个都消失了,然后重新启动外壳。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.