El nombre complejo de la rama de Git rompió todos los comandos de Git

338

Estaba tratando de crear una rama mastercon el siguiente comando,

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

cuando Git de repente dejó de responder. Sospecho que los no escapados ()tienen la culpa, de alguna manera. Ahora, cada vez que intento ejecutar cualquier comando de Git, aparece el mismo error:

git:176: command not found: _of_ProductSearchQuery

con el número después de gitaumentar cada vez que escribo un comando.

¿Alguien puede explicar lo que pasó? ¿Y cómo vuelvo a la normalidad? Me gustaría eliminar esa rama, pero ¿cómo puedo hacer eso?

ruipacheco
fuente
8
Supongo que esto está relacionado con su entorno zsh, ya que pude ejecutar crear la rama en mi shell bash sin efectos secundarios (lubuntu 13.10), pero veo el error cuando cambio a mi zsh totalmente vainilla
Jonathan.Brink
27
En el futuro, cita cosas que parezcan sospechosas. git branch "SSLOC-201_Implement___str__()_of_ProductSearchQuery"funciona bien
Qix - MONICA FUE MALTRATADA el
11
@Qix Es mejor evitar por completo los caracteres problemáticos.
jub0bs
3
@Jubobs Definitivamente, aunque he visto que ciertas compañías imponen nombres de sucursales extraños como este.
Qix - MONICA FUE MALTRATADA el
1
@DwightSpencer Su enlace es específico de Bash, pero esta pregunta es específica de zsh. El problema en realidad no ocurre en Bash.
jub0bs

Respuestas:

617

Problema

¿Alguien puede explicar lo que pasó? [...] Me encantaría poder eliminar esa rama, pero Git no funcionará para mí.

Mediante la ejecución

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

en zsh, no creaste ninguna rama . En su lugar, definió accidentalmente tres funciones de shell , llamadas git, branchy SSLOC-201_Implement___str__, que ignoran sus parámetros (si los hay) y de quién es el cuerpo _of_ProductSearchQuery. Puede verificar por sí mismo que esto es lo que sucedió, invocando el comando incorporado zsh llamado functions, que enumera todas las funciones de shell existentes:

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

Desafortunadamente, aunque las otras dos funciones de shell no son problemáticas, la función de shell llamada "git" ahora oculta el comando de buena fe 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)

Por lo tanto, posteriormente recibirá el error

command not found: _of_ProductSearchQuery

cada vez que intente ejecutar un comando Git, por ejemplo git log, git statusetc. (suponiendo, por supuesto, que no _of_ProductSearchQueryexiste ningún comando llamado ).

Nota al margen

[...] Me sale el mismo error:

git:176: command not found: _of_ProductSearchQuery

(con el número después de gitaumentar cada vez que escribo un comando)

Ese número simplemente corresponde al valor de HISTCMD, una variable de entorno que contiene

[l] l número de evento del historial actual en un shell interactivo, en otras palabras, el número de evento para el comando que causó la $HISTCMDlectura.

Consulte el manual de zsh para más detalles.

Solución

¿Y cómo vuelvo a la normalidad?

Simplemente elimine la función de shell problemática (y las otras dos que creó por accidente, mientras está en ello):

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

Entonces todo debería estar bien.

¿Y si unsettambién está sombreado?

Buena pregunta ! Os remito al excelente comentario de Wumpus W. Wumbley a continuación.


Consejos para nombrar sucursales

Evita los caracteres especiales de shell

Sí, como se señala en los comentarios, los paréntesis son caracteres válidos en los nombres de rama de Git; solo necesita citar el nombre apropiadamente, ej.

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

Sin embargo, la necesidad de citar dichos nombres cada vez que se usan como argumentos de línea de comandos debería convencerlo de que evite los paréntesis en los nombres de referencia. En términos más generales, debe (tanto como sea posible) evitar los personajes que tienen un significado especial en las conchas, para evitar sorpresas como esta.

Use nombres de rama simples

Debes mantener los nombres de tus sucursales cortos y dulces de todos modos. Descripciones largas como

SSLOC-201_Implement ___ str __ () _ of_ProductSearchQuery

pertenecer a mensajes de confirmación, no a nombres de sucursal.

jub0bs
fuente
44
Nada en ese hilo dice que los padres son ilegales. A Git parecía gustarle bien. Switched to a new branch 'abcd-()-foo'
Qix - MONICA FUE MALTRATADA el
1
Se ve bien; Definitivamente no es una buena idea usarlos, pero no son técnicamente inválidos.
Qix - MONICA FUE MAL
12
¿Qué sucede si alguien también se sombrea unsetcreando la llamada función de shell? (¿es esto posible?)
Matteo Umili
2
@codroipo ¡Ja! Ese es un buen punto. Sí, es posible y, en ese caso, probablemente sea mejor reiniciar zsh.
jub0bs
45
Podrías usar builtin unset. Si builtiny unsetambos han sido sombreados por funciones, entonces unfunction. Si eso se ha ido también unhash -f. Si los cuatro de los que se han ido, a continuación, reinicie la cáscara.