Como posso fazer esse alias git com aspas funcionar?

Sep 17 2020

Eu quero fazer um apelido git diff que mostra apenas as linhas alteradas (coloridas).

[alias]
    mdiff = diff --color | grep --color=never $'^\e\[3[12]m'

Isso não funciona, pois aparentemente os canais não podem ser usados ​​em aliases git, mas esta resposta mostra uma solução alternativa :

[alias]
    mdiff = ! git diff --color | grep --color=never $'^\e\[3[12]m'

No entanto, isso também não funciona e ainda recebo este erro: fatal: bad config line 17 in file /home/me/.config/git/config

Um comentário abaixo dessa resposta sugere que o problema se deve às citações.

Respostas

2 Gilles'SO-stopbeingevil' Sep 17 2020 at 03:40

Um alias git sem !é executado pelo próprio Git. Se o alias contém um |caractere, é apenas um |caractere. Nenhuma concha está envolvida, então |não significa um cano.

Um alias git começando com !é executado por um shell. Git executa o que segue !em um shell (depois de fazer uma análise de citação) e passa os argumentos no final. Sua segunda tentativa não é válida porque o Git analisa as barras invertidas, você precisa dobrá-las e dobrar a barra invertida na frente de, [pois o shell deve ver \\[para que o grep veja \[:

mdiff = ! git diff --color | grep --color=never $'\\e\\\\[3[12]m'

Mas isso não está certo porque git mdiff fooé equivalente a executar o comando shell

git diff --color | grep --color=never $'\\e\\\\[3[12]m' foo

Você precisa organizar para passar os argumentos para git. Você pode fazer isso definindo uma função e, em seguida, executando-a. Você precisa ter cuidado porque ;precisa ser citado. Isso funciona no lado do Git:

mdiff = ! "f () { git diff --color \"$@\" | grep --color=never $'\\e\\\\[3[12]m'; }; f"

Isso só funciona se /bin/shfor bash, não se for dash. Dash não suporta a $'…'sintaxe de escape. Se /bin/shfor um traço, você precisará produzir o caractere de escape com printf.

mdiff = ! "f () { git diff --color \"$@\" | grep --color=never $(printf '\\033\\\\[3[12]'); }; f"

Se tudo que você quer fazer é remover o contexto (mas manter nomes de arquivos e indicadores de posição), que é construído em: git diff -U0.