Контекстно-зависимое слияние? - PullRequest
32 голосов
/ 21 февраля 2011

Существует ли какой-либо инструмент сравнения / слияния для языков программирования, который работает с учетом синтаксиса (например, XML Diff Tool), выполняя нечто большее, чем построчное сравнение (и, при необходимости, игнорируя пробелы).

Меня интересует программа, которая на самом деле следует синтаксису языка и разделителям, предлагая изменения без нарушения синтаксической корректности или объединяя операторы, разделенные на несколько строк. Пример поведения будет:

* при обнаружении if(){, который вводит дополнительный уровень вложенности, автоматически связывает закрывающую скобку } несколькими строками ниже с ней.)

* держите совпадающие элементы синтаксиса вместе, избегайте глупостей, таких как удаление блока, которое имеет тенденцию создавать:

 int function_A()
 { 
     int ret;
     ret = something;
     ret += something_else;

      return ret;
  }

  int function_B()
  { 
     if(valid)
     {
         int ret;
         ret = something;
         ret += something_else;

          return ret;
      }

       else return -1;
  }

Лично я хотел бы найти программное обеспечение, способное обрабатывать синтаксис C ++, но было бы интересно узнать о решениях для других языков.

Ответы [ 8 ]

20 голосов
/ 18 апреля 2013

Семантическое слияние .
Поддерживаемые языки с веб-сайта:

Мы начали с C # и Vb.net, затем добавили Java.Теперь C уже поддерживается, а затем мы сосредоточимся на C ++, Objective-C и JavaScript, в зависимости от ваших отзывов

14 голосов
/ 25 февраля 2011

Хотя KDiff3 не сравнивает элементы синтаксиса в контексте грамматики, он имеет более высокую степень детализации, чем "вся строка изменена", и будет выделять, какие именно части в строке изменяются.

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

Comparision of function_A and function_B

И даже в этом случае, если алгоритм не соответствует желаемому, например, как показано ниже:

Comparision of old and new function_A

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

Альтернатива 1:

Comparision of old and new function_A with sync1

Альтернатива 2:

Comparision of old and new function_A with sync2

11 голосов
/ 03 марта 2011

Звучит так, будто вас заинтересует алгоритм Брейм Коэна (создатель BitTorrent) Patience Diff (который используется в системе контроля версий на базаре).

См. Проблема различий была решена и особенно Преимущества разницы в терпении :

Выдержка из второй ссылки:

Другое преимущество разницы в терпении состоит в том, что он часто не соответствует линиям, которые просто не должны совпадать. Например, если вы полностью переписали часть кода, она не должна совпадать с пустыми строками в каждой версии, как показано в этом примере . Наконец, вот этот пример:

 void func1() {
     x += 1
 }

+void functhreehalves() {
+    x += 1.5
+}
+
 void func2() {
     x += 2
 }

Это просто и очевидно, но часто используемые алгоритмы интерпретируют это так:

 void func1() {
     x += 1
+}
+
+void functhreehalves() {
+    x += 1.5
 }

 void func2() {
     x += 2
 }
9 голосов
/ 02 марта 2011

Beyond Compare делает то, что вы просите.Он не поддерживает синтаксическую корректность и не сравнивает языковые блоки одновременно, но может выполнять следующие действия:

  • Некоторое понимание синтаксиса языка, поэтому он может выделять синтаксис сравниваемых файлов и можеттакже распознавать и при необходимости игнорировать несущественные различия (например, комментарии, включая многострочные комментарии).
  • Поддержка использования внешних программ преобразования для загрузки и сохранения данных.Из коробки поддерживается использование этой функции для предварительной проверки XML и HTML перед их сравнением.Вы можете настроить GNU Indent для стандартизации синтаксиса, прежде чем сравнивать два файла C.
  • Необязательные веса строк, чтобы вы могли придать больший вес соответствию, например закрывающим скобкам.Я не пробовал эту функцию.
  • Замены, чтобы игнорировать для одного сеанса каждое место, где old_variable_name слева был заменен на new_variable_name справа.

Это, безусловно, лучший инструмент сравнения и слияния, который я использовал.Он также кроссплатформенный, дешевый (30 долларов за стандартную, 50 долларов за профессиональную) и очень щедрый период оценки, так что стоит попробовать.

6 голосов
/ 07 марта 2012

Пожалуйста, посмотрите на Сравните ++ .

Может выполнять структурированное сравнение с учетом языка для C / C ++, Java, C #, Javascript, CSS, ... и при необходимости игнорировать комментарии, чисто отформатированные, пробелы и изменения регистра и иметь уникальную возможность выравнивать перемещенные разделы, такие как функция C ++, пространство имен Java, метод C #, селектор CSS, ...

6 голосов
/ 26 февраля 2011

См. Наши SmartDifferencer инструменты.

SmartDifferencers зависят от языка, управляются синтаксическими анализаторами качества производства, строят AST и сравнивают деревья. Это делает их полностью независимыми от разметки текста и промежуточных комментариев; Примечательно, что они невосприимчивы к изменениям в тексте литералов (основание, смещение десятичной точки + показатель изменения, различные escape-последовательности), если фактическое значение, представленное литералом, не отличается. Результат сообщается в терминах синтаксиса языка и возможных действиях по редактированию (перемещение, копирование, вставка, удаление, переименование идентификатора в блоке).

Существуют версии для C #, Java, C ++, Python и множества других языков. Примеры каждого из них на веб-сайте.

SmartDifferencer существует для C, но анализ файлов C без полной командной строки компилятора иногда проблематичен, поэтому иногда происходит сбой, и вам приходится прибегать к более примитивным инструментам сравнения, таким как diff. Мы работаем над улучшением этой ситуации.

3 голосов
/ 03 марта 2011

Если вы используете eclipse, встроенный редактор сравнения обеспечивает поддержку синтаксиса diff / merge, по крайней мере для Java. Установите флажок «Автоматически сравнивать структуру» в настройках «Общие / Сравнить / Исправить», затем выберите «Сравнение структуры Java» в редакторе сравнения.

1 голос
/ 04 сентября 2017

Посмотрите на https://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools особенно столбец Структурное сравнение.

В настоящее время есть только два инструмента, которые понимают структуру языка.

  • Сравнить ++ (отлично работает на C ++)
  • Pretty Diff (инструмент сравнения кода с поддержкой языков для нескольких веб-языков. Он также украшает, минимизирует и некоторые другие вещи ..)

К сожалению, во многих инструментах этот столбец все еще пуст.

...