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 gitalias 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 -cavec 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/configou 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 gitalias - puis gitajoute 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 $0soit le nom de fichier du script. Mais pour une gitfonction d'alias, l' $0argument 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 configcitation 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.
$1devrait fonctionner).