Je viens de tomber sur un sujet similaire ; j'espère que je peux poster mes notes. Une chose qui me rend confus à propos de git
alias avec des arguments, vient probablement de l' git help config
(J'ai la version 1.7.9.5 de git) :
Si l'expansion de l'alias est préfixée d'un point d'exclamation, elle sera traitée comme une commande shell. Par exemple, en définissant "alias.new = !gitk --all --not ORIG_HEAD", l'invocation de "git new" est équivalente à l'exécution de la commande shell "gitk --all --not ORIG_HEAD". Notez que les commandes shell seront exécutées depuis le répertoire de premier niveau d'un référentiel, qui n'est pas nécessairement le répertoire courant. [...]
De la manière dont je le vois - si un alias "sera traité comme une commande shell" lorsqu'il est préfixé par un point d'exclamation - pourquoi aurais-je besoin d'utiliser une fonction, ou sh -c
avec des arguments ; pourquoi ne pas simplement écrire ma commande telle quelle ?
Je ne connais toujours pas la réponse - mais je pense qu'en fait, il y a une légère différence dans le résultat. Voici un petit test - mettez ceci dans votre ordinateur. .git/config
ou votre ~/.gitconfig
:
[alias]
# ...
ech = "! echo rem: "
shech = "! sh -c 'echo rem:' "
fech = "! f() { echo rem: ; }; f " # must have ; after echo!
echargs = "! echo 0[[\"$0\"]] 1-\"$1\"/ A-"$@"/ "
fechargs = "! f() { echo 0[[\"$0\"]] 1-\"$1\"/ A-"$@"/ ; }; f "
Voici ce que j'obtiens en utilisant ces alias :
$ git ech word1 word2
rem: word1 word2
$ git shech word1 word2
rem:
$ git fech word1 word2
rem:
$ git echargs word1 word2
0[[ echo 0[["$0"]] 1-"$1"/ A-$@/ ]] 1-word1/ A-word1 word2/ word1 word2
$ git fechargs word1 word2
0[[ f() { echo 0[["$0"]] 1-"$1"/ A-$@/ ; }; f ]] 1-word1/ A-word1 word2/
... ou : lorsque vous utilisez une commande "simple" après l'option !
"tel quel" dans un git
alias - alors git
ajoute automatiquement la liste des arguments à cette commande ! Une façon d'éviter cela, est en effet, d'appeler votre script comme une fonction - ou comme argument à la commande sh -c
.
Une autre chose intéressante ici (pour moi), est que dans un shell script, on s'attend typiquement à la variable automatique $0
pour être le nom de fichier du script. Mais pour un git
la fonction alias, la $0
L'argument est, fondamentalement, le contenu de la tout le site chaîne de caractères spécifiant cette commande (telle que saisie dans le fichier de configuration).
C'est pourquoi, je suppose, si vous faites une erreur de citation - dans le cas ci-dessous, il s'agirait d'échapper aux guillemets extérieurs :
[alias]
# ...
fail = ! \"echo 'A' 'B'\"
... - alors git
échouerait avec (pour moi, du moins) un message quelque peu cryptique :
$ git fail
"echo 'A' 'B'": 1: echo 'A' 'B': not found
fatal: While expanding alias 'fail': ' "echo 'A' 'B'"': No such file or directory
Je pense que, depuis git
"a vu" une chaîne entière comme un seul argument à !
- il a essayé de l'exécuter comme un fichier exécutable, et par conséquent il n'a pas réussi à trouver "echo 'A' 'B'"
comme un fichier.
En tout cas, dans le contexte de la git help config
Dans le cas de la citation ci-dessus, je pense qu'il est plus exact d'affirmer quelque chose comme : " ... l'invocation "git new" est équivalente à l'exécution de la commande shell "gitk --all --not ORIG_HEAD $@", où $@ sont les arguments passés à l'alias de la commande git depuis la ligne de commande au moment de l'exécution. ... ". Je pense que cela expliquerait également pourquoi l'approche "directe" du PO ne fonctionne pas avec les paramètres de position.
22 votes
Notez que dans git 1.8.2.1, il est possible de faire cela sans fonction shell (votre approche originale avec
$1
devrait fonctionner).10 votes
@Eimantas Souhaitez-vous développer dans une réponse ? Cela ne fonctionne pas pour moi, et je ne trouve aucune documentation à ce sujet.
1 votes
@Eimantas il n'y a rien à propos de cela dans la notes de mise à jour cependant.
2 votes
Je peux confirmer que je peux exécuter des commandes shell avec des arguments sans aucun problème dans Git 2.11.
0 votes
@Eimantas Pouvez-vous peut-être créer une réponse avec une explication détaillée ?