Come ignorare le linee spostate in un diff


11

Attualmente sto lavorando a uno strumento di generazione del codice sorgente. Per assicurarsi che le mie modifiche non introducano nuovi bug, difftra l'output del programma prima e dopo le mie modifiche sarebbe teoricamente uno strumento prezioso.

Tuttavia, questo risulta essere più difficile di quanto si possa pensare, perché lo strumento genera linee in cui l'ordine non ha importanza (come importdichiarazioni, dichiarazioni di funzioni, ...) in un modo ordinato in modo semi-casuale. Per questo diffmotivo , l'output di è ingombro di molte modifiche che in realtà sono solo le righe spostate in un'altra posizione nello stesso file.

C'è un modo per far sì che diff ignori queste mosse e produca solo le righe che sono state veramente aggiunte o rimosse?


Forse è più facile cambiare il tuo strumento per generare funzioni e importare dichiarazioni in un ordine specifico (es. Lessicografico, se possibile nella tua lingua)?
Daniel Beck

@Daniel Beck: vedi sotto il mio commento alla risposta di Gilles.
dnadlinger,

Vecchio soggetto, ma per riassumere commenti qui sotto, come sarebbe questo diffstrumento in grado di separare le mosse validi da quelli non validi, come Ordine di istruzioni in codice fa materia, e casi in cui questo non è vero sono limitati (importazioni, dichiarazione di funzioni e classi, eccetera.) ?
Joël,

@ Joël: La risposta è semplicemente che sapevo che i cambiamenti del generatore che dovevo testare non avrebbero introdotto alcun bug relativo alla modifica dell'ordine delle linee. Naturalmente, è necessario uno strumento basato su un parser per la lingua di destinazione per evitare falsi positivi nel caso generale (o semplicemente una suite di test completa per il generatore), ma si supponeva che si trattasse di un rapido controllo una tantum in aggiunta per la revisione del codice.
dnadlinger,

Risposte:


2

Potresti fare un semplice diff, memorizzare il risultato da qualche parte (per evitare un altro diff), scorrere le linee in entrambe le versioni, quindi rimuovere quelle dall'altro lato.

Ciò ha generato un progetto separato per il codice di lavoro. Il codice.


Non sono sicuro di cosa dovrebbe fare esattamente, ma non sembra produrre i risultati desiderati. Come capisco la domanda, dai due esempi nel codice /tmp/olde /tmp/newnon si desidererebbero risultati diff poiché ci sono solo righe che sono state spostate. Questo codice tuttavia produce risultati.
Ilari Kajaste,

Risolto il codice
l0b0

Non ho testato la risposta quando ho finito il processo di fusione sopra menzionato molto tempo fa, ma da uno sguardo al codice sembra che funzioni.
dnadlinger,

4

Puoi provare a ordinarli prima. Qualcosa di simile a:

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

Bash (e zsh) possono farlo in una riga con la sostituzione del processo

diff <(sort file-a) <(sort file-b)

Questa potrebbe essere un'opzione, ma le differenze generate non sarebbero molto utili, perché
perderei

Anche se sto ancora sperando in una soluzione migliore, ho seguito questo approccio per verificare il batch di modifiche su cui avevo lavorato.
dnadlinger,

2
Posso prevedere dove questo perderebbe alcuni cambiamenti. A volte l'ordine conta, a volte no. Scarti tutto il contesto.
Rich Homolka,

Per un refattore di ordini in cui volevo assicurarmi che tutto ciò che esisteva esistesse, questo era esattamente ciò di cui avevo bisogno.
ntrrobng,

0

Sembra che tu abbia il controllo dello strumento. Quindi rendi prevedibile il suo output: invece di emettere dichiarazioni in un ordine semi-casuale, usa (diciamo) l'ordine alfabetico come ultima risorsa. Ciò non solo avrà il vantaggio di rimuovere inutili trapianti da diff, ma anche di rendere più facile la lettura e la verifica dell'output dello strumento per un essere umano.


Mi dispiace, ma questa risposta non mi aiuta affatto - se fosse così facile, la cambierei subito. Inoltre, attualmente sto unendo le modifiche a un progetto da cui il generatore è stato originariamente biforcato, quindi l'aggiunta di un cambiamento di così vasta portata complicherebbe ulteriormente questo processo ...
dnadlinger,

0

Se il file è strutturato in sezioni, sono solo le sezioni che sono fuori servizio, ed esiste un'espressione regolare che puoi usare per riconoscere l'intestazione della sezione, puoi suddividere i file nelle loro sezioni e poi confrontare le sezioni in modo accoppiato.

Ad esempio, l'ho appena fatto su due dump MySQL per confrontarli dopo che alcuni dei nomi del database avevano cambiato caso (e quindi il dump li ha elencati in un ordine diverso):

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.