Git alias avec les paramètres positionnels
Fondamentalement, je suis en train de faire un alias:
git files 9fa3
...pour exécuter la commande:
git diff --name-status 9fa3^ 9fa3
mais git ne semble pas passer des paramètres positionnels de la commande alias. J'ai essayé:
[alias]
files = "!git diff --name-status $1^ $1"
files = "!git diff --name-status {1}^ {1}"
...et quelques autres, mais ceux qui n'ont pas de travail.
Le cas dégénéré serait:
$ git echo_reverse_these_params a b c d e
e d c b a
...comment puis-je faire ce travail?
- Notez que dans git 1.8.2.1 il est possible de le faire sans fonction shell (l'original de votre approche avec
$1
devrait fonctionner). - Pourriez-vous élaborer une réponse? Il ne fonctionne pas pour moi, et je ne trouve pas de documentation à ce sujet.
- il n'y a rien à ce sujet dans le notes de version bien que.
- je peux confirmer que je peux exécuter des commandes shell avec des arguments sans manigances dans Git 2.11.
Vous devez vous connecter pour publier un commentaire.
La façon la plus évidente est d'utiliser une fonction shell:
Un alias sans
!
est traitée comme une commande Git; par exemple,commit-all = commit -a
.Avec le
!
, il est exécuté en tant que sa propre commande dans le shell, vous permettant d'utiliser plus de la magie de ce genre.UPD
Parce que les commandes sont exécutées à la racine du référentiel que vous pouvez utiliser
${GIT_PREFIX}
variable en se référant aux noms de fichier dans les commandes!
est nécessaire au début de la définition de la fonction? Merci!!
est traitée comme une commande Git; par exemple,commit-all = commit -a
. Avec le!
, il est exécuté en tant que sa propre commande dans le shell, vous permettant d'utiliser plus de la magie de ce genre.sta = status
etst = sta
) échoue avec une erreur de message comme: "xy n'est pas une commande git". Merci pour l'info!!
sera exécuté à la racine du référentiel, donc l'utilisation de chemins relatifs lors de l'appel de votre alias ne donnera pas les résultats que vous pouvez attendre.fatal: bad revision '^'
. Ce que vous attendez, il n'est qu'une question de goût. Sans doute, vous voulez l'exécuter sur la TÊTE. Cela permettrait d'atteindre cet objectif:files = "!f() { git diff --name-status \"${1:-HEAD}\"^ \"${1:-HEAD}\"; }; f"
. Alternativement, et, éventuellement, saner, vous voulez exécuter à l'encontre de l'arbre de travail:files = "!f() { [ -n \"$1\" ] && git diff --name-status \"$1\"^ \"$1\" || git diff --name-status; }; f"
.Vous pouvez également référence
sh
directement (au lieu de créer une fonction):(Notez le tiret à la fin de la ligne, vous en aurez besoin.)
sh
, puisque c'est en soi une coquille, et il est disponible sur la grande majorité des systèmes. En utilisant le shell par défaut ne fonctionne que si la commande fonctionne comme écrit pour tous les shells.--
à-
car il est plus familier et moins susceptibles de accidentellement dire stdin à un certain point. ("Un argument de est équivalent à --" en bash(1) est ungoogleable)-
et--
et obtenu les deux lignes d'erreursh: -c: line 0: unexpected EOF while looking for matching
"sh: -c: line 1: syntax error: unexpected end of file
avec bash 4.2.1 sur cygwin.sh -c
) est également inutile. Voir ma réponse pour une alternative.sh
a cassé--
de la manipulation (et-
est simplement faux) pour des raisons de compatibilité. Je serai d'accord de votre meilleur pari est d'écrire l'alias dans la forme de la accepté de répondre et supposons que l'utilisateur du shell POSIX sh assez compatible.L'alias que vous cherchez est:
Avec l'argument de validation:
La final
#
est important - il empêche tous les utilisateurs-les arguments fournis en cours de traitement par l'interpréteur de commandes (observations) des.Remarque:
git
met tout utilisateur des arguments fournis à la fin de la ligne de commande. Pour le voir en action, essayez:GIT_TRACE=2 git files a b c d
L'échappement (en raison de la nidification) citations sont importants pour les noms de fichiers contenant des espaces ou des
"; rm -rf --no-preserve-root /;
)!
implique déjàsh -c
(affiché quand ajoutantGIT_TRACE=2
), donc il n'y a pas besoin d'exécuter un sous-shell. Quelles questions avez-vous voir dans les cas les plus compliqués?fp = "! 1=${1:-$(git headBranch)}; 2=${2:-up}; git fetch -fu $2 pull/$1/head:$1; git checkout $1; git branch -u $2 #"
. Cela fonctionne très bien sans les deux premiers énoncés, mais tombe vers le bas si vous les utilisez. (J'aiheadBranch = symbolic-ref --short HEAD
ainsi).fp = "! a=${1:-$(git headBranch)}; b=${2:-up}; git fetch -fu $b pull/$a/head:$a; git checkout $a; git branch -u $b #"
."
les guillemets sont nécessaires?git cat
de commande, reportez-vous à stackoverflow.com/a/54819889/24468Utilisation GIT_TRACE=1 décrit sur le git de la page de manuel pour faire de l'alias de traitement transparent:
Vos commandes d'origine travailler avec git version 1.8.3.4 (Eimantas de noter ce qui a changé dans 1.8.2.1).
La
sh -c '..' --
etf() {..}; f
options à la fois proprement gérer le "$@" paramètres de différentes façons (voir avec GIT_TRACE). En ajoutant "#" à un alias permettrait également les paramètres positionnels sans quitter la fuite ceux.files = "!git diff --name-status $1^ $1 #"
files = "!git diff --name-status $1^"
Comme l'a déclaré Drealmer ci-dessus:
GIT_PREFIX
définie par git pour le sous-répertoire que vous êtes dans, vous pouvez contourner cela en modifiant tout d'abord le répertoire :cd ${GIT_PREFIX:-.} &&.
" (source: stackoverflow.com/a/21929373/266309)!cd "${GIT_PREFIX:-.}" && ls -al
Je voulais le faire avec un alias qui fait cela:
En fin de compte, j'ai créé un script shell nommé git-m qui a ce contenu:
Cela a l'avantage que c'est beaucoup plus lisible parce que c'est sur plusieurs lignes. En Plus j'aime être en mesure d'appeler bash avec
-x
etset -e
. Vous pouvez probablement le faire de toute cette affaire comme un alias, mais il serait super laid et difficile à maintenir.Parce que le fichier est nommé
git-m
vous pouvez l'exécuter comme ceci:git m foo bar
'!f() { : git branch ; ... }; f'
et saisie semi-automatique de l'alias comme une branche qui est super pratique..bashrc
fichier que j'source. Mais je ne pense pas changer la façon dont je l'auto-complétion des arguments d'un script d'autant que le script lui-même, et il avait seulement être en cours de dev.Juste tombé sur quelque chose de similaire, j'espère que c'est oK d'après mes notes. Une chose qui me confond sur
git
des alias avec des arguments, vient probablement de lagit help config
(j'ai la version git 1.7.9.5):La façon dont je vois ça - si un alias "sera traitée comme une commande shell" quand le préfixe avec le point d'exclamation - pourquoi aurais-je besoin pour utiliser une fonction, ou
sh -c
avec des arguments, pourquoi ne pas simplement écrire ma commande en tant que-est?Je ne sais toujours pas la réponse mais je crois qu'effectivement il y a une légère différence dans le résultat. Voici un petit test de jeter dans votre
.git/config
ou votre~/.gitconfig
:Voici ce que je reçois à l'exécution de ces alias:
... ou: lorsque vous utilisez un "bon de commande" après le
!
"en" en ungit
alias - alorsgit
ajoute automatiquement à la liste des arguments de la commande! Une façon de l'éviter, est en effet, à l'appel de votre script soit comme une fonction - ou comme argument poursh -c
.Une autre chose intéressante ici (pour moi), c'est que dans un script shell, on s'attend généralement la variable automatique
$0
être le nom de fichier du script. Mais pour ungit
alias de la fonction, la$0
argument est, pour l'essentiel, le contenu de la ensemble chaîne spécifiant la commande (saisie dans le fichier de config).C'est pourquoi, je suppose, si vous arrive d'erreur dans la citation - dans le cas ci-dessous, ce serait échapper à l'extérieur des guillemets:
... - puis
git
échouerait avec (pour moi, au moins) un peu cryptique message:Je pense que, depuis
git
"vu" une chaîne entière comme un seul argument à!
- il essayé de l'exécuter en tant que fichier exécutable; et, en conséquence, il a échoué à trouver"echo 'A' 'B'"
comme un fichier.En tout cas, dans le contexte de la
git help config
citation ci-dessus, je préfère imaginer que c'est plus exact de dire quelque chose comme: "... l'invocation "git nouveau" est équivalent à l'exécution de la commande shell "gitk --tous --pas ORIG_HEAD $@", où $@ sont les arguments passés à la commande git alias à partir de la ligne de commande lors de l'exécution. ... ". Je pense que ce serait également expliquer pourquoi le "direct" de l'approche à l'OP ne fonctionne pas avec les paramètres positionnels.fail
tente d'exécuter la commande "echo" A ""B" (ie. 10 caractères de long). Même erreur desh -c "'echo a b'"
et même cause, trop de couches de citations