Como ignorar linhas movidas em um diff

11

Atualmente, estou trabalhando em uma ferramenta de geração de código fonte. Para garantir que minhas alterações não apresentem novos bugs, um diffentre a saída do programa antes e depois das minhas alterações seria teoricamente uma ferramenta valiosa.

No entanto, isso acaba sendo mais difícil do que se imagina, porque a ferramenta gera linhas em que a ordem não importa (como importinstruções, declarações de função, ...) de maneira ordenada de maneira semi-aleatória. Por esse diffmotivo , a saída de é cheia de muitas mudanças que, na verdade, são apenas linhas movidas para outra posição no mesmo arquivo.

Existe uma maneira de fazer com que diff ignore esses movimentos e apenas produza as linhas que foram realmente adicionadas ou removidas?

dnadlinger
fonte
Talvez seja mais fácil alterar sua ferramenta para gerar funções e importar declarações em uma ordem específica (por exemplo, lexicográfica, se possível no seu idioma)?
Daniel Beck
@ Daniel Beck: Veja meu comentário à resposta de Gilles 'abaixo.
precisa saber é o seguinte
Assunto antigo, mas para resumir os comentários abaixo, como essa diffferramenta seria capaz de separar movimentos válidos dos inválidos, pois a Ordem das instruções no código é importante e os casos em que isso não é verdade são limitados (importações, declaração de funções e classes, etc.)?
Joël
@ Joël: A resposta é simplesmente que eu sabia que as alterações do gerador que eu tinha que testar não apresentariam nenhum erro relacionado à alteração da ordem das linhas. Obviamente, você precisa de uma ferramenta baseada em um analisador para o idioma de destino para evitar falsos positivos no caso geral (ou simplesmente um conjunto de testes abrangente para o seu gerador), mas isso também deveria ser uma verificação rápida e pontual. para codificar revisão.
dnadlinger

Respostas:

2

Você pode fazer uma comparação simples, armazenar o resultado em algum lugar (para evitar outra comparação), percorrer as linhas nas duas versões e removê-las do outro lado.

Isso gerou um projeto separado para o código de trabalho. O código.

l0b0
fonte
Não sei ao certo o que isso deve fazer exatamente, mas não parece produzir os resultados desejados. Pelo que entendi, os dois exemplos no código /tmp/olde /tmp/newnenhum resultado diff seriam desejados, já que existem apenas linhas que foram movidas. Este código, no entanto, produz resultados.
Ilari Kajaste
Corrigido o código.
L0b0
Ainda não testei a resposta ao concluir o processo de mesclagem mencionado há muito tempo, mas, olhando de relance para o código, parece que ele poderia funcionar.
dnadlinger
4

Você pode tentar classificá-los primeiro. Algo como:

sort file-a > s-file-a
sort file-b > s-file-b
diff s-file-a s-file-b

O Bash (e zsh) pode fazer isso em uma linha com substituição de processo

diff <(sort file-a) <(sort file-b)
cYrus
fonte
Esta pode ser uma opção, mas os diffs gerados não seria muito útil, em seguida, porque eu perderia todo o número da linha e contexto informações ...
dnadlinger
Mesmo que ainda esteja esperando uma solução melhor, segui essa abordagem para verificar o lote de alterações nas quais estava trabalhando.
Ndlinglinger 5/12
2
Eu posso prever onde isso perderia algumas mudanças. Às vezes a ordem é importante, às vezes não. Você descarta todo o contexto.
Rich Homolka
Para um refatorador de pedidos, onde eu queria ter certeza de que tudo o que existia ainda existe, era exatamente isso que eu precisava.
Ntrrobng 6/04/2017
0

Parece que você tem controle sobre a ferramenta. Em seguida, torne sua saída previsível: em vez de emitir declarações em uma ordem semi-aleatória, use (digamos) a ordem alfabética como último recurso. Isso não apenas terá o benefício de remover detritos inúteis dos diffs, mas também de facilitar a leitura e a verificação da saída da ferramenta para um ser humano.

Gilles 'SO- parar de ser mau'
fonte
Desculpe, mas esta resposta não me ajuda em nada - se fosse tão fácil, eu mudaria imediatamente. Além disso, estou actualmente a fusão mudanças a partir de um projeto do gerador foi originalmente bifurcada de, assim que adicionar tal, em vez de longo alcance mudança iria complicar esse processo ainda mais ...
dnadlinger
0

Se o arquivo estiver estruturado em seções, são apenas as seções que estão fora de ordem e existe uma expressão regular que você pode usar para reconhecer o cabeçalho da seção, você pode dividir os arquivos em suas seções e comparar as seções aos pares.

Por exemplo, eu fiz isso em dois dumps do MySQL para compará-los depois que alguns nomes de banco de dados mudaram de caso (e, portanto, o dump os listou em uma ordem diferente):

csplit all-07sep2015-11:19:12.sql '/Current Database/-1' '{*}'  # split the dump made before the change, creating files xx00, xx01, ...
csplit -f yy all-07sep2015-12:26:12.sql '/Current Database/-1' '{*}' # split the dump made after the change, creating files yy00, yy01, ...
fgrep 'Current Database' xx?? yy?? | perl -lne 'BEGIN{my %foo}; /(^....).*`(.*)`/ and push(@{$foo{lc($2)}}, $1); END {printf("diff -di %s %s\n", @{$_}) for values %foo}' | sh -x | less  # match the pairs and compare them with diff
reinierpost
fonte