Як ігнорувати переміщені рядки в розл


11

Зараз я працюю над інструментом генерації вихідного коду. Щоб переконатися, що мої зміни не вносять нових помилок, diffміж результатами програми до і після моїх змін теоретично буде цінним інструментом.

Однак це виявляється важче, ніж можна було б подумати, тому що інструмент виводить рядки, де порядок не має значення (наприклад, importзаяви, функції декларацій ...) напів випадковим чином упорядкованим способом. Через це висновок diffутискається безліччю змін, які насправді лише рядки переміщуються на інше місце в тому ж файлі.

Чи є спосіб зробити diff ігнорувати ці рухи та вивести лише рядки, які дійсно були додані чи видалені?


Можливо, простіше змінити інструмент для генерації функцій та імпорту декларацій у певному (наприклад, лексикографічному, якщо можливо, вашою мовою) порядку?
Даніель Бек

@Daniel Beck: Дивіться мій коментар до відповіді Жиля нижче.
dnadlinger

Стара тема, але підсумовуючи коментарі нижче, як цей diffінструмент зміг би відокремити дійсні кроки від недійсних, оскільки Порядок інструкцій у коді має значення, а випадки, коли це не відповідає дійсності, обмежені (імпорт, декларація функцій та класів, тощо)?
Joël

@ Joël: Відповідь просто в тому, що я знав, що зміни генератора, які я повинен був перевірити, не внесуть помилок, пов'язаних зі зміною порядку рядків. Звичайно, вам потрібен інструмент, заснований на аналізаторі цільової мови, щоб уникнути помилок-позитивів у загальному випадку (або просто всебічний тестовий набір для вашого генератора), але це повинно було бути швидким одноразовим підтвердженням додатково для коду огляду.
dnadlinger

Відповіді:


2

Ви можете зробити просту дію, зберегти результат десь (щоб уникнути чергової різниці), провести крізь рядки в будь-якій версії, а потім видалити ті з іншого боку.

Це породило окремий проект робочого коду. Код.


Я не впевнений, що саме це має робити, але, здається, це не дає бажаних результатів. Наскільки я розумію питання, з двох прикладів у коді /tmp/oldі /tmp/newжодних відмінних результатів не потрібно, оскільки там просто перемістилися рядки. Однак цей код дає результати.
Іларі Каясте

Виправлений код.
l0b0

Я не перевіряв відповідь, коли я закінчив процес злиття, згаданий вище, давно, але з погляду коду, схоже, він може працювати.
dnadlinger

4

Ви можете спробувати сортувати їх спочатку. Щось на зразок:

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

Bash (і zsh) можуть зробити це в один рядок із заміною процесу

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

Це може бути варіантом, але згенерований розріз був би не дуже корисним, тому що я втратив всю інформацію про номер рядка та інформацію про контекст…
dnadlinger

Навіть якщо я все ще сподіваюся на краще рішення, я пішов із таким підходом до перевірки партії змін, над якими працював.
dnadlinger

2
Я можу передбачити, де це могло б пропустити деякі зміни. Іноді порядок має значення, іноді - ні. Ви відкидаєте весь контекст.
Багата Гомолка

Для рефактора замовлень, де я хотів переконатися, що все, що існувало, все ще є, саме це мені і було потрібно.
ntrrobng

0

Це здається, що ви маєте контроль над інструментом. Потім зробіть її результат передбачуваним: замість того, щоб випускати декларації у напів випадковому порядку, використовуйте (скажімо) алфавітний порядок як крайній захід. Це не тільки матиме вигоду від вилучення непотрібної сировини з розрізів, але й полегшить читання та перевірку результатів інструменту для людини.


Вибачте, але ця відповідь мені зовсім не допомагає - якби це було так просто, я би змінив її відразу. Крім того, в даний час я зливаю зміни від проекту, від якого генератор спочатку був роздвоєним, тому додавання такої досить далекосяжної зміни ще більше ускладнить цей процес…
dnadlinger

0

Якщо файл структурований у розділи, це лише ті розділи, які вийшли з ладу, і існує регулярний вираз, який ви можете використовувати для розпізнавання заголовка розділу, ви можете csplit файли в їх розділи, а потім порівняти розділи попарно.

Наприклад, я просто зробив це на двох дампах MySQL, щоб порівняти їх після того, як деякі імена бази даних змінили регістр (і тому дамп перелічив їх у іншому порядку):

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.