Le nom de branche Git complexe a cassé toutes les commandes Git

338

J'essayais de créer une branche masteravec la commande suivante,

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

quand Git a soudainement cessé de répondre. Je soupçonne que les échappés ()sont à blâmer, en quelque sorte. Maintenant, chaque fois que j'essaie d'exécuter une commande Git, j'obtiens la même erreur:

git:176: command not found: _of_ProductSearchQuery

avec le nombre après avoir gitaugmenté chaque fois que je tape une commande.

Quelqu'un peut-il expliquer ce qui s'est passé? Et comment revenir à la normale? Je voudrais supprimer cette branche, mais comment faire?

ruipacheco
la source
8
Je suppose que cela est lié à votre environnement zsh car j'ai pu exécuter la création de la branche dans mon shell bash sans aucun effet secondaire (lubuntu 13.10), mais je vois l'erreur lorsque je passe à mon zsh totalement vanille
Jonathan.Brink
27
À l'avenir, citez des choses qui semblent suspectes. git branch "SSLOC-201_Implement___str__()_of_ProductSearchQuery"fonctionne très bien.
Qix - MONICA A ÉTÉ BRUÉE le
11
@Qix Mieux vaut éviter complètement les personnages problématiques.
jub0bs
3
@Jubobs Certainement, même si j'ai vu certaines entreprises appliquer des noms de succursales étranges comme celui-ci.
Qix - MONICA A ÉTÉ BRUÉE le
1
@DwightSpencer Votre lien est spécifique à Bash, mais cette question est spécifique à zsh. Le problème ne se produit pas réellement dans Bash.
jub0bs

Réponses:

617

Problème

Quelqu'un peut-il expliquer ce qui s'est passé? [...] J'adorerais pouvoir supprimer cette branche, mais Git ne fonctionnera pas pour moi.

En exécutant

git branch SSLOC-201_Implement___str__()_of_ProductSearchQuery

dans zsh, vous n'avez créé aucune branche . Au lieu de cela, vous avez accidentellement défini trois fonctions shell , appelés git, branchet SSLOC-201_Implement___str__qui ne tiennent pas compte de leurs paramètres ( le cas échéant) et dont le corps est _of_ProductSearchQuery. Vous pouvez vérifier par vous-même que c'est bien ce qui s'est passé, en appelant la commande zsh intégrée appelée functions, qui répertorie toutes les fonctions shell existantes:

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

Malheureusement, bien que les deux autres fonctions de shell ne soient pas problématiques, la fonction de shell appelée "git" masque désormais la commande bona fide 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)

Par conséquent, vous obtiendrez ensuite l'erreur

command not found: _of_ProductSearchQuery

chaque fois que vous essayez d'exécuter une commande Git, par exemple git log, git statusetc. (en supposant, bien sûr, qu'aucune commande appelée _of_ProductSearchQueryn'existe).

Note d'accompagnement

[...] J'ai la même erreur:

git:176: command not found: _of_ProductSearchQuery

(avec le nombre après avoir gitaugmenté chaque fois que je tape une commande)

Ce nombre correspond simplement à la valeur de HISTCMD, une variable d'environnement qui contient

[t] le numéro d'événement historique actuel dans un shell interactif, c'est-à-dire le numéro d'événement de la commande qui a provoqué $HISTCMDla lecture.

Voir le manuel zsh pour plus de détails.

Solution

Et comment revenir à la normale?

Supprimez simplement la fonction shell problématique (et les deux autres que vous avez créées par accident pendant que vous y êtes):

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

Alors tout devrait bien se passer.

Et si elle unsetest également masquée?!

Bonne question ! Je vous renvoie à l'excellent commentaire de Wumpus W. Wumbley ci-dessous.


Conseils pour nommer les succursales

Évitez les caractères spéciaux du shell

Oui, comme indiqué dans les commentaires, les parenthèses sont des caractères valides dans les noms de branche Git; il vous suffit de citer le nom de manière appropriée, par exemple

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

Cependant, la nécessité de citer ces noms à chaque fois lorsqu'ils sont utilisés comme arguments de ligne de commande devrait vous convaincre d'éviter les parenthèses dans les noms de référence. Plus généralement, vous devriez (autant que possible) éviter les personnages qui ont une signification particulière dans les coquilles, pour éviter des surprises comme celle-ci.

Utilisez des noms de branche simples

Vous devez de toute façon garder vos noms de succursales courts et doux. Des descriptions longues comme

SSLOC-201_Implement ___ str __ () _ of_ProductSearchQuery

appartiennent aux messages de validation, pas aux noms de branche.

jub0bs
la source
4
Rien dans ce fil n'indique que les parens sont illégaux. Git semblait l'aimer très bien. Switched to a new branch 'abcd-()-foo'
Qix - MONICA A ÉTÉ BRUÉE le
1
Cela semble bon; certainement pas une bonne idée de les utiliser, mais ils ne sont pas techniquement invalides.
Qix - MONICA A ÉTÉ BRUÉE le
12
Que se passe-t-il si quelqu'un unsetcrée également des ombres en créant une fonction shell appelée? (est-ce possible?)
Matteo Umili
2
@codroipo Ha! C'est un bon point. Oui, c'est possible, et dans ce cas, vous feriez probablement mieux de redémarrer zsh.
jub0bs
45
Vous pourriez utiliser builtin unset. Si builtinet unsetont tous deux été masqués par des fonctions, alors unfunction. Si cela a disparu aussi unhash -f. Si les quatre d' entre eux sont partis, puis redémarrer le shell.