Git Alias ​​- Commandes et paramètres multiples

186

J'essaie de créer un alias qui utilise à la fois plusieurs commandes Git et des paramètres de position. Il y a des pages Stackoverflow pour chacune, et il semblerait douloureusement évident de faire les deux, mais j'ai des problèmes.

Par exemple, je veux passer à la branche foo et effectuer un statut. Donc dans mon .gitconfig, j'ai:

  [alias] 
     chs = !sh -c 'git checkout $0 && git status'

ce qui ne marche pas. Alors que quelque chose comme ça fonctionnera.

chs = !sh -c 'git checkout $0'

echoes = !sh -c 'echo hi && echo bye'

Toute idée serait appréciée.

Stella
la source
Mon alias: git config --global alias.go '! Git commit -a && git pull --rebase && git push && git status'. Remarque: utilisez des guillemets simples.
Marcus Becker

Réponses:

160

Cela fonctionnera (testé avec zsh et bash):

[alias] chs = !git checkout $1 && git status
Olivier Verdier
la source
1
Non, ce ne sera pas le cas. Git se transformera git chs fooengit checkout && git status foo
Lily Ballard
24
Intéressant, git remplit actuellement les variables de position dans les alias de shell. Mais il est toujours cassé, car il les utilise également comme arguments. Un alias de echo $1 && echo done, lorsqu'il est appelé avec l'argument 'foo', affichera à la fois "foo" et "done foo".
Lily Ballard
7
À quoi sert le point d'exclamation précédent lors de la première invocation de git?
Elijah Lynn
21
@ElijahLynn: Dans un alias git, un premier !moyen passe le tout au shell. Sinon, cela suppose que vous essayez d'exécuter une autre commande git et la transmet comme arguments au gitbinaire.
Lily Ballard
2
@Brondahl Clever. Je recommanderais ;:plutôt && :que. Et cela fonctionne très bien aussi sous Unix.
Lily Ballard
86

Cela cible Windows batch / msysgit bash; peut ne pas fonctionner sur d'autres environnements.

Comme l'ont dit Olivier Verdier et Lily Ballard

[alias] chs = !git checkout $1 && git status

fonctionne presque, mais donne une fausse insertion supplémentaire de l'argument ...

git chs demo -> git checkout demo && git status demo

Mais si vous ajoutez && :à la fin de votre alias, alors l'argument faux est consommé dans une balise d'emplacement.

Donc

[alias] chs = !git checkout $1 && git status && :

donne la sortie correcte ... git chs demo -> git checkout demo && git status

Brondahl
la source
10
Le && :est d'or et fait fonctionner cette solution pour les commandes où l'argument supplémentaire serait problématique.
Clay
3
@Clay (ou n'importe qui d'autre) - Quelqu'un pourrait-il expliquer au défié BASH ce que && :fait?
Justin Morgan
7
@JustinMorgan && signifie que si la commande précédente tourne à 0 (succès), exécutez la commande après &&. ':', le signe deux-points, est une commande interne du shell, qui ne fait rien d'autre que développer des arguments et effectuer des redirections et renvoyer le statut 0. Voici quelques utilisations: 1. a=123;$aerreurs, mais a=123; : $apas. 2. : > hello.txtvide hello.txt. 3. if [ "$a" = "hello" ];then : ;fifonctionne correctement mais les erreurs sans ":". C'est comme passen python. 4. : this is a comment, les deux points suivis d'un espace fonctionnent comme #dans une ligne de commentaire.
ElpieKay
3
c'est un tel hack ... git devrait accepter le mode de commande multiple
kchoi
1
Merci @ElpieKay pour l'explication. Mon alias git local pour un projet était co = !git checkout public/compiled && git checkout $1et quand je le ferais, git co masterje recevais le message error: pathspec 'master' did not match any file(s) known to git.. Je ne pensais pas que cette réponse me serait utile car la première chose qu'elle mentionne est Windows et je suis sous Linux. Mais tu as expliqué pourquoi.
Tyler Collier le
74

Vous pouvez définir une fonction shell.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"
Lily Ballard
la source
J'ai vu cela sur une autre page stackoverflow, mais mon terminal cygwin dit que la fonction n'est pas reconnue lorsque j'essaye de l'exécuter.
Stella
@Stella: J'ai laissé une citation de fermeture là-dedans qui n'est pas utile cette syntaxe de fichier de configuration. Assurez-vous que vous ne l'avez pas.
Lily Ballard
2
Wow ... Malheureusement, tout cela était un problème de version. J'utilisais Git 1.7.3, et aucune de ces méthodes ne fonctionnait. J'ai mis à jour la version 1.7.6 et voilà, tout a fonctionné. Merci les gars!
Stella
5
si vous utilisez Windows, je pense que vous devez entourer la définition de la fonction shell avec des guillemets doubles"
drzaus
4
La réponse d'Olivier n'a pas fonctionné pour moi en utilisant les paramètres (OSX). Cela a parfaitement fonctionné.
Ohad Schneider
26

J'ai pu créer des alias git multi-lignes et assez complexes. Ils fonctionnent bien sur Windows mais je suppose qu'ils fonctionneraient également ailleurs, par exemple:

safereset = "!f() { \
                trap 'echo ERROR: Operation failed; return' ERR; \
                echo Making sure there are no changes...; \
                last_status=$(git status --porcelain);\
                if [[ $last_status != \"\" ]]; then\
                    echo There are dirty files:;\
                    echo \"$last_status\";\
                    echo;\
                    echo -n \"Enter Y if you would like to DISCARD these changes or W to commit them as WIP: \";\
                    read dirty_operation;\
                    if [ \"$dirty_operation\" == \"Y\" ]; then \
                        echo Resetting...;\
                        git reset --hard;\
                    elif [ \"$dirty_operation\" == \"W\" ]; then\
                        echo Comitting WIP...;\
                        git commit -a --message='WIP' > /dev/null && echo WIP Comitted;\
                    else\
                        echo Operation cancelled;\
                        exit 1;\
                    fi;\
                fi;\
            }; \
            f"

J'ai écrit un article et j'ai quelques autres exemples ici .

VitalyB
la source
3
une amélioration à cela serait d'ajouter !f() { : resetpour obtenir les complétions de la commande de réinitialisation github.com/git/git/blob/master/contrib/completion
un utilisateur
Bon travail! Sous quelle licence cet article est-il publié? Cela vous dérangerait-il si j'en traduisais certaines parties pour StackOverflow en russe?
Nick Volynkin
@NickVolynkin Désolé pour la réponse tardive. Merci et bien sûr, allez-y :)
VitalyB
23
[alias]
chs = !git branch && git status
FractalSpace
la source
9
Quel est le !pour?
AutonomousApps
1
Je n'ai pas pu trouver de doc pour le !mais pour autant que je puisse voir, git par défaut supposera que l'alias est une commande git donc t = statusfonctionnera. Cependant, si vous essayez, t = git statuscela ne fonctionnera pas (dira "git" command not found). Alors que là où le !vient, il lui dit d'exécuter la commande comme s'il s'agissait d'un shell, et normalement vous en avez besoin lorsque vous avez plusieurs commandes git par alias, donc vous pouvez avoir t = !git status && git logpar exemple et cela fonctionnera.
laurent
1
Voici une question StackOverflow qui traite des points d'exclamation (!) Dans les alias Git: stackoverflow.com/questions/21083933/… .
Jacob Lockard
Si le développement d'alias est précédé d'un point d'exclamation , il sera traité comme une commande shell . git-scm.com/docs/git-config
Rohim Chou
6

Essaye celui-là:

[alias]
    chs = "!sh -c 'git checkout \"$0\" && git status'"

Appelez ça comme ça: git chs master

Brocksamson
la source
6

Il est possible d'avoir un alias git multiligne en ajoutant \à la fin de chaque ligne.

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "
Gmarik
la source
2
Merci! Je n'ai eu aucun problème à utiliser"!git fetch --prune --all; git pull --rebase upstream master; git push origin master" pour mon alias.
Droogans
3

Le problème ici est que les paramètres de position semblent être envoyés deux fois à la commande shell (à partir de git 1.9.2). Pour voir ce que je veux dire, essayez ceci:

[alias]
  test = !git echo $*

Alors fais git test this is my testing string. Vous devriez observer la sortie suivante (deux dernières lignes éditées ici pour plus de clarté):

03:41:24 (release) ~/Projects/iOS$ git test this is my testing string
this is my testing string this is my testing string
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
          #1                         #2

Une façon de contourner ce problème serait de

[alias]
  chs = !git checkout $1 && git status && git echo x >/dev/null

Cela consommera le paramètre positionnel supplémentaire lors de son application à cette dernière commande d'écho et n'aura aucun effet sur les résultats.

Ben Collins
la source
Votre exemple sera étendu à: git echo ceci est ma chaîne de test ceci est ma chaîne de test L'ajout d'un # à la fin le corrigera (n'oubliez pas les guillemets autour de l'alias de commande).
imme le
dans .gitconfig: a0 = "! echo $ *" et a1 = "! echo $ * #". Pour les tester: git a0 hallo daar; git a1 hallo daar
imme le
0

Un exemple pour les personnes qui veulent essayer ce que font différents alias.

Mettre ceci dans la section alias du fichier de configuration de GIT (par exemple ~/.gitconfig):


    [alias]
        a0 = "!echo $*"
        a1 = "!echo $* #"
        a2 = "!f () { echo \"$*\"; }; f "
        a3 = "!f () { echo \"$*\"; }; f #"
        a4 = "!f () { echo \"$*\"; }; f \"$*\" #"
        a5 = "!f () { echo \"$*\"; }; f \"$@\" #"
        a6 = "!f () { echo \"$*\"; }; f \"$1\" #"

Et puis en exécutant cette commande:


    cat ~/.gitconfig | grep --extended-regexp -- '(a[0-9])|(alias)' ; \
    echo "" ; \
    export CMD ; \
    for I in {0..6} ; \
    do \
        CMD="a""${I}" ; \
        echo -n "Executing alias.${CMD} = " ; \
        git config --global alias."${CMD}" ; \
        git $CMD 'hoi daar' en nu? ; \
        git $CMD hoi daar en nu? ; \
        echo "" ; \
    done ; \
    unset CMD ;

Devrait donner ceci en sortie:


    [alias]
       a0 = "!echo $*"
       a1 = "!echo $* #"
       a2 = "!f () { echo \"$*\"; }; f "
       a3 = "!f () { echo \"$*\"; }; f #"
       a4 = "!f () { echo \"$*\"; }; f \"$*\" #"
       a5 = "!f () { echo \"$*\"; }; f \"$@\" #"
       a6 = "!f () { echo \"$*\"; }; f \"$1\" #"
    
    Executing alias.a0 = !echo $*
    hoi daar en nu? hoi daar en nu?
    hoi daar en nu? hoi daar en nu?
    
    Executing alias.a1 = !echo $* #
    hoi daar en nu?
    hoi daar en nu?
    
    Executing alias.a2 = !f () { echo "$*"; }; f 
    hoi daar en nu?
    hoi daar en nu?
    
    Executing alias.a3 = !f () { echo "$*"; }; f #
    
    
    
    Executing alias.a4 = !f () { echo "$*"; }; f "$*" #
    hoi daar en nu?
    hoi daar en nu?
    
    Executing alias.a5 = !f () { echo "$*"; }; f "$@" #
    hoi daar en nu?
    hoi daar en nu?
    
    Executing alias.a6 = !f () { echo "$*"; }; f "$1" #
    hoi daar
    hoi

imme
la source