git log -G<regex> -p
é uma ferramenta maravilhosa para pesquisar no histórico de uma base de código alterações que correspondam ao padrão especificado. No entanto, pode ser esmagador localizar o pedaço relevante na saída do diff / patch em um mar de pedaços principalmente irrelevantes.
É claro que é possível pesquisar a saída da git log
string / regex original, mas isso faz pouco para reduzir o ruído visual e a distração de muitas alterações não relacionadas.
Continuando lendo git log
, vejo --pickaxe-all
que há exatamente o oposto do que eu quero: ele amplia a saída (para todo o conjunto de alterações), enquanto eu quero limitá-lo (para o pedaço específico).
Essencialmente, estou procurando uma maneira de "inteligentemente" analisar o diff / patch em pedaços individuais e, em seguida, executar uma pesquisa em cada pedaço (visando apenas as linhas alteradas), descartar os pedaços que não coincidem e produzir os mesmos isso faz.
Existe uma ferramenta como eu descrevo? Existe uma abordagem melhor para obter os pedaços correspondentes / afetados?
Algumas pesquisas iniciais que fiz ...
Se fosse possível obter
grep
a saída diff / patch e tornar dinâmicos os valores das opções de contexto - digamos, através de regexps em vez de contagens de linha -, isso seria suficiente. Masgrep
não é exatamente construído dessa maneira (nem estou necessariamente solicitando esse recurso).Encontrei a suíte patchutils , que inicialmente parecia ser adequada às minhas necessidades. Mas depois de ler suas
man
páginas, as ferramentas não parecem lidar com pedaços correspondentes com base em regexps. (Eles podem aceitar uma lista de pedaços, no entanto ...)Finalmente encontrei o splitpatch.rb , que parece lidar bem com a análise do patch, mas seria necessário aumentar significativamente para lidar com a leitura dos patches
stdin
, a correspondência entre os blocos desejados e a saída dos blocos.
Respostas:
aqui /programming//a/35434714/5305907 é descrita uma maneira de fazer o que você está procurando. efetivamente:
git diff -U1 | grepdiff 'console' --output-matching=hunk
Ele mostra apenas os blocos que correspondem à string "console" fornecida.
fonte
grepdiff
é basicamente o que eu quero; Eu devo ter perdido a opção de correspondência de pedaços! no entanto ... as informações de confirmação do git são removidasgrepdiff
; portanto, depois de localizar o hunk relevante, você deve adivinhar o commit sha do objeto / blob sha no cabeçalho diff - uma operação bastante cara. (veja stackoverflow.com/a/223890/2284440 ) seria algo comogit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
grepdiff
mais barebones em termos de argumentos aceitos. note que quando o pedaço correspondente é o último pedaço de uma diff, ele inclui incorretamente o cabeçalho git commit do seguinte commit - algo que me confundiu completamente até que eu percebi o que estava acontecendo!Não é exatamente o que você está pedindo, mas uma maneira de lidar com os pedaços é o modo de adição interativa. Isso requer que você verifique o commit após o patch em que está interessado
então volte mais uma etapa no VCS, mas não no diretório de trabalho
(Nesse ponto, a diferença entre o índice e o diretório de trabalho corresponderá ao patch em que você está interessado.)
Agora você pode executar
git add -p
. Isso iniciará uma sessão interativa que tem uma/
opção, que permite localizar blocos nos quais alguma linha corresponde a um regex. Particularmente útil se você realmente quiser processar esses patches (como preparar uma palheta parcial).Infelizmente, pelo menos no momento, o
/
comandoadd -p
só funciona em um único arquivo; portanto, você pode precisar pular vários arquivos não relevantes.fonte
Com base na resposta acima do @nagu e nas outras respostas vinculadas, consegui
git log -G
mostrar apenas os trechos relevantes.Primeiro, crie um script em algum lugar do seu $ PATH com este conteúdo:
Ligue
git log -G
e diga ao Git para usar opickaxe-diff
script como um driver diff externo:Isso usará o script pickaxe-diff apenas para gerar os diffs, para que o restante da
git log
saída (commit hash, mensagem, etc.) permaneça intocado.Advertência
A maneira como a picareta Git funciona é que ela limita a saída aos arquivos cujos blocos alteram a sequência / regex especificada. Isso significa que, se outro pedaço desses arquivos também contiver a cadeia de caracteres de pesquisa / regex, mas não a alterar, ele ainda será exibido com o script acima. Esta é uma limitação do grepdiff. Há uma solicitação de recebimento aberto no projeto patchutils para adicionar um
--only-matching
sinalizador ao grepdiff, que forneceria a funcionalidade necessária para filtrar corretamente esses blocos.Eu escrevi minha solução nessa essência .
fonte