¿Cómo puedo agregar una function de shell en git alias con tubería?

Encontré una buena function de shell diff-lines () de Using git diff, ¿cómo puedo get líneas modificadas y agregadas?

Agregaré la function en mi file .bashrc , y funciona en mi command-line:

 [marslo@mppdev ~/Tools/Git/LinuxStuff] $ git diff -U0 | diff-lines Scripts/.marslorc:29:-# Inspinetworking from http://sofes.miximages.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers Scripts/.marslorc:29:+# Inspinetworking from http://sofes.miximages.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers/12179492#12179492 

Sin embargo, cuando traté de agregar el command como un alias git, aquí algo está mal:

 [marslo@mppdev ~/Tools/Git/LinuxStuff] $ cat ~/.gitconfig | grep "ldiff =" ldiff = "!bash -c 'git diff -U0' | diff-lines" [marslo@mppdev ~/Tools/Git/LinuxStuff] $ git ldiff sh: diff-lines: command not found fatal: Failed to run 'bash -c 'git diff -U0' | diff-lines' when expanding alias 'ldiff' 

Y, bash -c 'git diff -U0' | diff-lines bash -c 'git diff -U0' | diff-lines todavía funciona

 [marslo@mppdev ~/Tools/Git/LinuxStuff] $ bash -c 'git diff -U0' | diff-lines Scripts/.marslorc:29:-# Inspinetworking from http://sofes.miximages.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers Scripts/.marslorc:29:+# Inspinetworking from http://sofes.miximages.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers/12179492#12179492 

Aquí los detalles: ldff

El problema es que diff-lines es una function de shell y no un ejecutable real. Cuando ejecutas "!bash -c 'git diff -U0' | diff-lines" obtienes un error porque el intérprete de commands no está obteniendo tu ~/.bashrc y por lo tanto no sabe acerca de diff-lines . Este es el comportamiento normal de las shells: solo obtienen esas configuraciones en circunstancias específicas, y ejecutar un command no es una de ellas.

Así que aquí hay algunas recomendaciones. Primero, si la function de número de línea es buena fuera de git, considere hacer que diff-lines sea una secuencia de commands en lugar de solo una function de shell:

 #!/bin/bash diff-lines() { local path= local line= while read; do esc=$'\033' if [[ $REPLY =~ ---\ (a/)?.* ]]; then continue elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then path=${BASH_REMATCH[2]} elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then line=${BASH_REMATCH[2]} elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then echo "$path:$line:$REPLY" if [[ ${BASH_REMATCH[2]} != - ]]; then ((line++)) fi fi done } diff-lines 

Luego puede configurar su alias para que sea:

 ldiff = !sh -c 'git diff "$@" | diff-lines' - 

Esto también le permitirá pasar parameters a git ldiff , al igual que el command diff real. También puede usar diff-lines como su buscapersonas haciendo lo siguiente en su ~/.gitconfig :

 [pager] diff = diff-lines | less 

Luego, el command regular git diff se canalizará a través de su script diff-lines y finalmente a través de less para get la pagination. Utilizo ese mismo truco para resaltar las palabras cambios en las líneas.

Otra opción es lo que Adam mencionó: crea un script llamado git-ldiff que ejecuta tu command diff y lo canaliza a través de diff-lines

 #!/bin/bash diff-lines() { local path= local line= while read; do esc=$'\033' if [[ $REPLY =~ ---\ (a/)?.* ]]; then continue elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then path=${BASH_REMATCH[2]} elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then line=${BASH_REMATCH[2]} elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then echo "$path:$line:$REPLY" if [[ ${BASH_REMATCH[2]} != - ]]; then ((line++)) fi fi done } git diff "$@" | diff-lines 

Nota: esta es exactamente la misma secuencia de commands que la anterior con una pequeña modificación a la última línea.

En lugar de usar un alias:

  1. Pon tu código en una secuencia de commands,
  2. Nombre la secuencia de commands git-ldiff ,
  3. Utilice el chmod +x script para hacerlo ejecutable, y
  4. Coloque la secuencia de commands en un directory que esté en su RUTA.

Ahora, cuando git ldiff , git searchá y ejecutará tu scipt.