Подтвердить что ты не робот

Как я могу выполнить diff, который игнорирует все комментарии?

У меня есть большая база кода, которая была разветвлена ​​из исходного проекта, и я пытаюсь найти все отличия от оригинала. Многие изменения в файле состоят из прокомментированного кода отладки и других замечаний. Средство сравнения/слияния GUI под названием Meld под Ubuntu может игнорировать комментарии, но только однострочные комментарии.

Есть ли другой удобный способ найти только отличия, отличные от комментариев, либо с помощью инструмента GUI или инструментов командной строки linux? В случае, если это имеет значение, код представляет собой смесь PHP и Javascript, поэтому я в первую очередь заинтересован в игнорировании //, /* */ и #.

4b9b3361

Ответ 1

Чтобы использовать визуальный diff, вы можете попробовать DiffMerge. Его набор правил и параметры обеспечивают индивидуальное поведение.

В командной строке вы можете использовать опцию --ignore-matching-lines=RE для diff, например:

diff -d -I '^#' -I '^ #' file1 file2

Обратите внимание, что регулярное выражение должно совпадать с соответствующей строкой в ​​обоих файлах, и оно соответствует каждой измененной строке в hunk, чтобы работать, иначе она все равно покажет разницу.

Используйте одинарные кавычки для защиты шаблона от расширения оболочки и для выхода из зарезервированных символов с регулярным выражением (например, скобки).

Мы можем прочитать в diffutils руководство:

Однако -I игнорирует вставку или удаление строк, содержащих регулярное выражение, если каждая измененная строка в hunk (каждая вставка и каждое удаление) соответствует регулярному выражению.

Другими словами, для каждого неосведомляемого изменения diff выводит полный набор изменений в его окрестности, в том числе и неосведомленные. Вы можете указать более одного регулярного выражения для игнорируемых строк, используя более одного параметра -I. diff пытается сопоставить каждую строку с каждым регулярным выражением, начиная с последнего.

Это поведение также хорошо объясняется armel здесь.

Ответ 2

Смотрите нашу интеллектуальную систему Differencer, которая сравнивает исходные файлы на компьютере, используя структуру langauge, а не макет в качестве руководства. Это, в частности, означает, что он игнорирует комментарии и пробелы при сравнении кода.

Существует SmartDifferencer для PHP.

Ответ 3

Вы можете сначала отфильтровать оба файла с помощью stripcmt, который удалит комментарии C и С++. Для удаления комментариев # sed 's/#.*//' удалит их.

Конечно, вы сначала потеряете какой-то контекст при удалении комментариев, но, с другой стороны, различия в комментариях не вызовут никаких проблем. Я думаю, что сделал бы это, как и следующее (описано для одного файла, автоматизируйте по мере необходимости):

  • Если последняя версия исходной базы кода A и последняя скопированная база кода B, позвоните в комментарии удалены для A' и B' (например, сохраняйте их во временные файлы во время обработки).
  • Найдите общую версию исходного кода и разделите ее с текстом на O' (вместо этого просто используйте B' для этого).
  • Выполните трехстороннее слияние O', A' и B' и сохраните до C'. KDiff3 - отличный инструмент для этого.
  • Теперь у вас есть изменения кода, которые вы хотите объединить, однако C' без комментариев, поэтому вернитесь в "обычный" режим, выполните новое слияние 3-way с A' в качестве базы и A и C'. Это подберет изменения между A' и C' (который изменяет код, который вы хотите), в нормальную базу кода с комментариями на основе версии A.

Рисунки деревьев версий на бумаге перед началом работы настоятельно рекомендуется получить четкое представление о том, какие версии вы хотите использовать. Но не ограничивайте себя тем, что показывает дерево, вы можете объединить любую версию и в любом направлении, если вы просто выясните, какие версии использовать.

Ответ 4

Try:

diff -I REGEXP -I REGEXP2 file1 file 2

Смотрите: Регулярное выражение в Википедии

Ниже приведены примеры регулярных выражений, которые могут привести к тому, что diff игнорирует директиву препроцессора и как стандартные стандартные блоки комментариев.

В примере:

\#*\n
/***/
//*\n

Ответ 5

gnu diff поддерживает игнорирование строк, которые соответствуют регулярному выражению:

diff --ignore-matching-lines='^#' file1 file2

и для папок:

diff -[bB]qr --ignore-matching-lines='^#' folder1/ folder2/

Это игнорирует все строки, начинающиеся С# в начале строки.

Ответ 6

diff <file1> <file2> | grep -v '^[<>]\ #'

Далек от совершенства, но он даст представление о различиях