Git Alias: múltiples comandos y parámetros


182

Estoy tratando de crear un alias que use múltiples comandos de Git y parámetros posicionales. Hay páginas de Stackoverflow para cada una, y parecería dolorosamente obvio hacer ambas cosas, pero estoy teniendo problemas.

Como ejemplo, quiero cambiar a branch foo y realizar un estado. Entonces en mi .gitconfig, tengo:

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

que no funciona Mientras que algo como esto funcionará.

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

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

Cualquier idea sería apreciada.


Mi alias: git config --global alias.go '! Git commit -a && git pull --rebase && git push && git status'. Nota: Use comillas simples.
— Marcus Becker

Respuestas:


157

Esto funcionará (probado con zsh y bash):

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

1
No, no lo hará. Git se transformará git chs fooengit checkout && git status foo
— Lily Ballard

24
Interesante, git en realidad completa las variables posicionales ahora en alias de shell. Pero todavía está roto, porque también los agrega como argumentos. Un alias de echo $1 && echo done, cuando se invoca con el argumento 'foo', generará tanto "foo" como "done foo".
— Lily Ballard

77
¿Cuál es el signo de exclamación anterior para la primera invocación de git?
— Elijah Lynn el

21
@ElijahLynn: en un alias git, un !medio principal pasa todo al shell. De lo contrario, supone que está intentando ejecutar otro comando git y lo pasa como argumentos al gitbinario.
— Lily Ballard

2
@Brondahl Clever. Sin embargo, lo recomendaría en ;:lugar de && :. Y eso también funciona bien en Unix.
— Lily Ballard

82

Esto apunta a Windows batch / msysgit bash; podría no funcionar en otros entornos.

Como han dicho Olivier Verdier y Lily Ballard

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

casi funciona, pero da una inserción extra espuria del argumento ...

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

Pero si agrega && :al final de su alias, el argumento falso se consume en una etiqueta de ubicación.

Entonces

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

da la salida correcta ... git chs demo -> git checkout demo && git status


9
El && :es oro y hace que esta solución funcione para comandos donde el argumento adicional sería problemático.
— Clay

3
@Clay (o cualquier otra persona) - ¿Podría alguien explicarle a BASH-desafiado qué && :hace?
— Justin Morgan

77
@JustinMorgan && significa que si el comando anterior se convierte en 0 (éxito), ejecute el comando después de &&. ':', los dos puntos, es un comando integrado de shell, que no hace nada más que expandir argumentos y realizar redirecciones y devolver el estado 0. Aquí hay algunos usos: 1. a=123;$aerrores, pero a=123; : $ano lo hace. 2. : > hello.txtvacía hello.txt. 3. if [ "$a" = "hello" ];then : ;fifunciona bien pero errores sin ':'. Es como passen python. 4. : this is a comment, los dos puntos seguidos por el espacio funcionan como #en una línea de comentario.
— ElpieKay

2
este es un truco ... git debería aceptar el modo de comando múltiple
— kchoi

1
Gracias @ElpieKay por la explicación. Mi alias git local para un proyecto era co = !git checkout public/compiled && git checkout $1y cuando lo hiciera git co masterrecibiría el mensaje error: pathspec 'master' did not match any file(s) known to git.. No pensé que esta respuesta fuera útil para mí porque lo primero que menciona es Windows y estoy en Linux. Pero explicaste por qué.
— Tyler Collier

73

Puede definir una función de shell.

[alias] chs = "!f(){ git checkout \"$1\" && git status; };f"

Vi esto en otra página de stackoverflow, pero mi terminal cygwin dice que la función no se reconoce cuando intento ejecutarla.
— Stella

@Stella: dejé una cita de cierre allí que no es útil esta sintaxis del archivo de configuración. Asegúrate de no tenerlo.
— Lily Ballard

2
Wow ... Desafortunadamente, todo esto fue un problema de versión. Estaba usando Git 1.7.3, y ninguno de estos métodos funcionó. Actualicé a 1.7.6 y listo, todo funcionó. ¡Gracias chicos!
— Stella

55
si usa Windows, creo que debe rodear la definición de la función de shell con comillas dobles"
— drzaus

44
La respuesta de Olivier no funcionó para mí usando parámetros (OSX). Esto funcionó perfectamente.
— Ohad Schneider

25

Pude crear alias git de varias líneas y bastante complejos. Funcionan bien en Windows, pero supongo que también funcionarían en otro lugar, por ejemplo:

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"

Escribí una publicación y tengo algunos ejemplos más aquí .


2
una mejora para esto sería agregar !f() { : resetpara obtener terminaciones del comando de reinicio github.com/git/git/blob/master/contrib/completion/…
— un usuario

¡Gran trabajo! ¿Bajo qué licencia se publica ese artículo? ¿Te importaría si traduzco partes de él para StackOverflow en ruso?
— Nick Volynkin

@NickVolynkin Lo siento por la respuesta tardía. Gracias y, por supuesto, adelante :)
— VitalyB

22
[alias]
chs = !git branch && git status

8
¿Para qué sirve !?
— AutonomousApps

1
No pude encontrar el documento para el !pero, por lo que puedo ver, git supondrá de forma predeterminada que el alias es un comando git, por t = statuslo que funcionará. Sin embargo, si lo intentas t = git status, no funcionará (dirá el comando "git" no encontrado). Entonces, cuando !entra, le dice que ejecute el comando como si fuera un shell, y normalmente lo necesita cuando tiene múltiples comandos git por alias, por lo que puede tener, t = !git status && git logpor ejemplo, y funcionará.
— Laurent

Aquí hay una pregunta de StackOverflow que trata con signos de exclamación (!) En alias Git: stackoverflow.com/questions/21083933/… .
— Jacob Lockard

6

Prueba este:

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

Llámalo así: git chs master


6

Es posible tener un alias git multilínea agregando \al final de cada línea.

[alias] 
   chs = "!git checkout $1 \ 
          ; git status     \
         "

2
¡Gracias! En realidad no tuve problemas "!git fetch --prune --all; git pull --rebase upstream master; git push origin master"para usar mi alias.
— Droogans

3

El problema aquí es que los parámetros posicionales parecen estar siendo enviados al comando de shell dos veces (a partir de git 1.9.2). Para ver a qué me refiero, prueba esto:

[alias]
  test = !git echo $*

Entonces hazlo git test this is my testing string. Debe observar el siguiente resultado (las dos últimas líneas editadas aquí para mayor claridad):

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

Una forma de evitar esto sería

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

Esto consumirá el parámetro posicional adicional a medida que se aplique a ese último comando de eco y no tendrá ningún efecto en los resultados.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.