Je suis juste tombé sur quelque chose de similaire; j'espère que c'est ok pour poster mes notes. Une chose qui me confond à propos des git
alias avec des arguments, vient probablement de git help config
(j'ai la version 1.7.9.5 de git):
Si l'extension d'alias est précédé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 "git new" équivaut à exécuter la commande shell "gitk --all --not ORIG_HEAD". Notez que les commandes shell seront exécutées à partir du répertoire de niveau supérieur d'un référentiel, qui n'est pas nécessairement le répertoire courant. [...]
La façon dont je le vois - si un alias "sera traité comme une commande shell" lorsqu'il est préfixé avec 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'il y a en fait une légère différence de résultat. Voici un petit test - jetez-le dans votre .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 exécutant 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 "ordinaire" après le !
"tel quel" dans un git
alias - puis git
ajoute automatiquement la liste des arguments à cette commande! Un moyen de l'éviter est en effet d'appeler votre script soit comme une fonction, soit comme argument de sh -c
.
Une autre chose intéressante ici (pour moi), c'est que dans un script shell, on s'attend généralement à ce que la variable automatique $0
soit le nom de fichier du script. Mais pour une git
fonction d'alias, l' $0
argument est, fondamentalement, le contenu de la chaîne entière spécifiant cette commande (telle qu'elle est entrée dans le fichier de configuration).
C'est pourquoi, je suppose, si vous vous trompez - dans le cas ci-dessous, cela échapperait aux doubles guillemets externes:
[alias]
# ...
fail = ! \"echo 'A' 'B'\"
... - git
échouerait alors avec (pour moi, au 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, puisque git
"vu" une chaîne entière comme un seul argument à !
- il a essayé de l'exécuter comme un fichier exécutable; et en conséquence, il n'a pas réussi à trouver "echo 'A' 'B'"
un fichier.
Dans tous les cas, dans le contexte de la git help config
citation ci-dessus, je suppose qu'il est plus précis de dire quelque chose comme: " ... l'invocation" git new "équivaut à exécuter la commande shell" gitk --all --not ORIG_HEAD $ @ ", où $ @ sont les arguments passés à l'alias de commande git depuis la ligne de commande lors de l'exécution. ... ". Je pense que cela expliquerait également pourquoi l'approche "directe" dans OP ne fonctionne pas avec les paramètres de position.
$1
devrait fonctionner).