Ele está implementado agora (git 1.9 / 2.0, Q1 2014) com a introdução pathspec magic :(exclude)e sua forma abreviada:! em commit ef79b1f e commit 1649612 , de
Nguyễn Thái Ngọc Duy ( pclouds) , a documentação pode ser encontrada aqui .
Agora você pode registrar tudo, exceto o conteúdo de uma subpasta:
git log -- . ":(exclude)sub"
git log -- . ":!sub"
Ou você pode excluir elementos específicos dessa subpasta
um arquivo específico:
git log -- . ":(exclude)sub/sub/file"
git log -- . ":!sub/sub/file"
qualquer arquivo dentro de sub:
git log -- . ":(exclude)sub/*file"
git log -- . ":!sub/*file"
git log -- . ":(exclude,glob)sub/*/file"
Você pode tornar essa exclusão insensível a maiúsculas e minúsculas!
git log -- . ":(exclude,icase)SUB"
Como Kenny Evitt observou
Se você estiver executando o Git em um shell Bash, use ':!sub'ou ":\!sub"para evitar bash: ... event not founderros
Nota: Git 2.13 (Q2 2017) adicionará um sinônimo ^para!
Consulte commit 859b7f1 , commit 42ebeb9 (08 de fevereiro de 2017) de Linus Torvalds ( torvalds) .
(Fundido por Junio C Hamano - gitster- no commit 015fba3 , 27 de fevereiro de 2017)
pathspec magic: adicione ' ^' como alias para ' !'
A escolha de ' !' para um pathspec negativo acaba não apenas por não corresponder ao que fazemos para as revisões, mas também é um caractere horrível para a expansão do shell, uma vez que precisa ser citado.
Portanto, adicione ' ^' como um alias alternativo para uma entrada de exclusão de pathspec.
Observe que, antes do Git 2.28 (Q3 2020), o uso de pathspec negativo, enquanto os caminhos de coleta, incluindo os não rastreados na árvore de trabalho, foi interrompido.
Consulte commit f1f061e (05 de junho de 2020) de Elijah Newren ( newren) .
(Fundido por Junio C Hamano - gitster- no commit 64efa11 , 18 de junho de 2020)
dir: corrigir tratamento de pathspecs negados
Relatado por: John Millikin
Assinado por: Elijah Newren
do_match_pathspec()começou a vida como match_pathspec_depth_1()e para correção só deveria ser chamado de match_pathspec_depth(). match_pathspec_depth()foi renomeado posteriormente para match_pathspec(), de modo que o invariante que esperamos hoje é aquele que do_match_pathspec()não tem chamadores diretos fora de match_pathspec().
Infelizmente, essa intenção foi perdida com a renomeação das duas funções e chamadas adicionais para do_match_pathspec()foram adicionadas nos commits 75a6315f74 (" ls-files: add pathspec matching for submodules", 2016-10-07, Git v2.11.0-rc0 - merge listado em batch # 11 ) e 89a1f4aaf7 (" dir: se nosso pathspec pode corresponder a arquivos em um diretório, recurse nele", 2019-09-17, Git v2.24.0-rc0).
Obviamente, ele do_match_pathspec()tinha uma vantagem importante sobre match_pathspec()- match_pathspec()codificaria os sinalizadores para um de dois valores e esses novos chamadores precisavam passar algum outro valor para os sinalizadores.
Além disso, embora a chamada do_match_pathspec()direta estivesse incorreta, provavelmente não havia nenhuma diferença na saída final observável, porque o bug apenas significava que fill_diretory()retornaria para diretórios desnecessários.
Como as verificações subsequentes de correspondência de caminho em caminhos individuais sob o diretório fariam com que esses caminhos extras fossem filtrados, a única diferença em usar a função errada era o cálculo desnecessário.
A segunda dessas chamadas ruins para do_match_pathspec()estava envolvida - via movimento direto ou via cópia + edição - em uma série de refatores posteriores.
Consulte os commits 777b420347 (" dir: sincronizar treat_leading_path()e read_directory_recursive()", 2019-12-19, Git v2.25.0-rc0 - mesclar ), 8d92fb2927 (" dir: substituir o algoritmo exponencial por um linear", 2020-04-01, Git v2.27.0 -rc0 - mesclagem listada no lote 5 ) e 95c11ecc73 ("Corrigir fill_directory()API propensa a erros ; torná-la apenas retornar correspondências", 2020-04-01, Git v2.27.0-rc0 - mesclagem listada no lote 5 ) .
O último deles introduziu o uso de do_match_pathspec()em um arquivo individual e, portanto, resultou no retorno de caminhos individuais que não deveriam ser.
O problema de chamar ao do_match_pathspec()invés de match_pathspec()é que qualquer padrão negado como '`:! Caminho_rejante`` será ignorado .
Adicione uma nova match_pathspec_with_flags()função para atender às necessidades de especificar sinalizadores especiais enquanto verifica corretamente os padrões negados, adicione um grande comentário acima do_match_pathspec()para evitar que outros o do_match_pathspec()usem indevidamente e corrija os chamadores atuais de para usarem match_pathspec()ou match_pathspec_with_flags().
Uma observação final é que DO_MATCH_LEADING_PATHSPECrequer consideração especial ao trabalhar com DO_MATCH_EXCLUDE.
O ponto DO_MATCH_LEADING_PATHSPECé que, se tivermos um pathspec como
*/Makefile
e estamos verificando um caminho de diretório como
src/module/component
que queremos considerá-lo uma correspondência para que possamos recursar no diretório porque _might_ tem um arquivo nomeado em Makefilealgum lugar abaixo.
No entanto, quando estamos usando um padrão de exclusão, ou seja, temos um pathspec como
:(exclude)*/Makefile
NÃO queremos dizer que um caminho de diretório como
src/module/component
é uma correspondência (negativa).
Enquanto lá possa haver um arquivo chamado 'Makefile' em algum lugar abaixo desse diretório, também pode haver outros arquivos e não podemos excluir preventivamente todos os arquivos nesse diretório; precisamos recurse e, em seguida, verificar os arquivos individuais.
Ajuste a DO_MATCH_LEADING_PATHSPEClógica para ser ativada apenas para pathspecs positivos.
!f() { git log ... | path/to/filter-log.pl "$@" | git log --stdin --no-walk; fou até mesmo envolver essa parte do pipeline no script.