Cómo incrustar un script bash directamente dentro de un alias de git

82

¿Puedo incrustar el siguiente código de shell bash:

for name in $(git diff --name-only $1); do git difftool $1 $name & done

directamente en la creación de un alias de git:

git config --global alias.diffall ***my-bash-code-here***

Esto conduce a mi pregunta / respuesta anterior sobre SO, donde puse el código en un archivo .sh y luego le asigné un alias al archivo:

git config --global alias.diffall '!sh diffall.sh'

Pero en la búsqueda interminable de simplicidad, ¿debe haber una forma de omitir el archivo e insertar código directamente en el alias? No puedo entender el formato ...

Seba Illingworth
fuente

Respuestas:

95
git config --global alias.diffall '!sh diffall.sh'

Esto es redundante en un sentido. Si va a agregar 'diffall.sh' en su $ PATH de todos modos, ¿por qué no guardarlo como 'git-diffall' y evitar declarar un alias? Sí, "git diffall" lo ejecutará.

u0b34a0f6ae
fuente
1
Ese. Es genial. Inicialmente me preocupé de ejecutar algo accidentalmente, ya que escribí algunos scripts de shell para hacer cosas de git y les di el prefijo 'git-', pero mi shell (zsh) no los completa automáticamente, tienes que escribirlos explícitamente. Y si quiero un comportamiento de autocompletar, puedo declarar un alias de git para su propio subcomando, que también es un requisito para hacer explícito el enlace del script al subcomando.
Jon Carter
1
Sí, y es un binario sólo tiene la explosión:! binary
1
No funciona para mí, el uso de un alias interno !sh git checkout $(git log --branches -1 --pretty=format:'%D' | sed 's/.*, //g')da como resultado /usr/lib/git-core/git: /usr/lib/git-core/git: cannot execute binary file. Lo probé con y sin shal principio.
Hi-Angel
36

Para ejecutar comandos dentro de un alias de git, y en particular para pasar argumentos a esos comandos, probablemente tendrá que crear una función temporal que luego invocará inmediatamente:

$ vim ~/.gitconfig
...
[alias]
    # compare:
    foo = "! echo begin arg=$1/$2/end"
    foo2 = "!f() { echo "begin arg=$1/$2/end"; }; f"

En este ejemplo, la función es probablemente lo que necesita (y también es más flexible en cuanto a lo que puede hacer en una sola "declaración"); y probablemente pueda decir que para ambas opciones, los argumentos restantes del comando git simplemente se pasan como argumentos al alias, independientemente de si es "echo" o "f"; invocar la función simplemente consume los argumentos, ignorando lo que no se usa explícitamente:

$ git foo a b c
begin arg=a/b/end a b c

$ git foo2 a b c
begin arg=a/b/end

Otro ejemplo (enumera todos los alias, según el patrón coincidente) (nota: puede seguir reutilizando el mismo nombre de función "f ()" en todo el .gitconfig):

[alias]
    alias = "!f() { git config --get-regexp "^alias.${1}$" ; }; f"

El primero devuelve el alias solo para "foo $", el segundo para "foo. *":

$ git alias foo
alias.foo ! echo begin arg=$1/$2/end

$ git alias 'foo.*'
alias.foo ! echo begin arg=$1/$2/end
alias.foo2 !f() { echo begin arg=$1/$2/end; }; f

(nb: los resultados reales pueden variar según el shell; estoy usando esto con bash en Linux, Unix y Cygwin (Windows)).

Miguel
fuente
git.wiki.kernel.org/index.php/Aliases#What.27s_new.3F recomienda implícitamente su uso sh -c, de esa manera no tiene que preocuparse por cuál es el shell de inicio de sesión del usuario.
clacke
la sintaxis de la función que he proporcionado es intencionalmente portátil en bastantes shells (sh / ksh / bash / zsh) y será más rápida que iniciar un subproceso. Recomendaría seguir usando la sintaxis de la función, a menos que haya un problema de portabilidad específico en una plataforma específica.
Michael
Tu comentario me trajo de regreso a esta respuesta, y probablemente usaré tu camino. Ahorra un nivel de cotización, y esos niveles ya son lo suficientemente locos. :-)
clacke
Parece un buen artículo que describe lo que está haciendo: atlassian.com/blog/git/advanced-git-aliases
Gabriel Staples
Nota: He publicado una pregunta de seguimiento con respecto a esta respuesta aquí: stackoverflow.com/questions/52123145/… . "Cómo reemplazar comandos internos de git, por ejemplo git status, con alias personalizados"
Gabriel Staples
24

No pude encontrarlo en la documentación, pero si crea un script "git- <name>" en la ruta, puede llamarlo con "git name" en su repositorio.

Ver:

$ cd ~/bin
$ echo "echo I love this log:
>pwd
>git log --graph  --summary --decorate --all" > git-logg
$ chmod +x git-logg
$ cd /path/to/your/repo
$ git logg
I love this log:
/path/to/your/repo
* commit 3c94be44e4119228cc681fc7e11e553c4e77ad04 (whatever-branch)
| Author: myself <my@Laptop.(none)>
| Date:   Fri Apr 1 16:47:20 2011 +0200
| 
|     would have been better not to do it at all
| 
...
$

Por lo tanto, también puede escribir cualquier alias que desee con esta forma (bastante oscura).

Aún más, puede agregar autocompletar a ese nuevo comando que define una función. Información aquí

$ _git_logg ()
{
  # you can return anything here for the autocompletion for example all the branches
  __gitcomp_nl "$(__git_refs)" 
}
albfan
fuente
+1, pensé que solo funcionaría desde la carpeta git libexec. gracias por compartir este consejo
Olivier Refalo
14

Agregar estas 2 líneas a su archivo .git / config debería ser suficiente.

[alias]
    diffall = '!for name in $(git diff --name-only $1); do git difftool $1 $name & done'

Editar: presumiblemente, la versión de git-config también funciona, pero me gusta mantener mis alias en el archivo de configuración para facilitar la administración.

Hay una bonita página en la wiki de git que explica los alias muy claramente: http://git.or.cz/gitwiki/Aliases En particular, lea 'alias avanzados con argumentos'

David Claridge
fuente
git config --global almacenará sus alias en $ HOME / .gitconfig, donde (IMO) son aún más fáciles de administrar; casi no es necesario que los alias sean específicos del repositorio. (Repo específico ir a repo / .git / config)
u0b34a0f6ae
Gracias David, pero simplemente no funcionará para mí, esa o cualquiera de las variaciones en el gran enlace que incluiste. ¿Quizás debería haber mencionado que estoy ejecutando en un entorno Windows? Gracias Kaizer, estuvo de acuerdo, esto es 'global' para mí.
Seba Illingworth
En estos días, git.wiki.kernel.org/index.php/Aliases#Advanced es un buen lugar para buscar. (el enlace git o cz redirecciona allí, pero esta sección en particular menciona la ejecución de cosas complejas con argumentos)
clacke
-4

(De la documentación de ProGit: http://progit.org/book/ch7-3.html )

¿Ha intentado agregar un script en .git / hooks?

Por ejemplo, si crea un script .git / hooks / post-checkout:

#!/bin/bash

echo "This is run after a 'git checkout'"

y luego ejecute el comando:

$ git checkout master
Switched to branch 'master'
This is run after a 'git checkout'
Denian
fuente
3
¿Qué tienen que ver los ganchos con la configuración, las extensiones y los alias?
Steve Buzonas