Контекстно-зависимое слияние?
Есть ли какой-либо инструмент diff/merge для языков программирования, который работает с поддержкой синтаксиса (например, 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;
Забастовкa >
return ret;
}
else return -1;
}
Забастовкa >
Лично я хотел бы найти программное обеспечение, способное обрабатывать синтаксис С++, но интересно было бы узнать о решениях для других языков.
Ответы
Ответ 1
Beyond Compare делает некоторые из того, что вы просите. Он не поддерживает синтаксическую корректность или сравнивает языковые блоки за раз, но может выполнять следующие действия:
- Некоторое понимание синтаксиса языка, поэтому он может делать подсветку синтаксиса сравниваемых файлов, а также может распознавать и, возможно, игнорировать несущественные различия (например, комментарии, включая многострочные комментарии).
- Поддержка использования внешних программ преобразования для загрузки и сохранения данных. Исходя из этого, он поддерживает это, чтобы префлотировать XML и HTML, прежде чем сравнивать его. Вы можете настроить GNU Indent для стандартизации синтаксиса перед сравнением двух файлов C.
- Дополнительные весы линий, чтобы дать вам более высокий вес для соответствия, например, закрытия фигурных скобок. Я не пробовал эту функцию.
- Замены, чтобы игнорировать в течение одного сеанса все места, где
old_variable_name
слева было заменено на new_variable_name
справа.
Это, безусловно, лучший инструмент сравнения и слияния, который я использовал. Это также кросс-платформенный, дешевый (30 долларов США для стандартных, 50 долларов США для профессионалов) и имеет очень щедрый период оценки, поэтому стоит попробовать.
Ответ 2
Семантическое слияние.
Языки поддерживаются с веб-сайта:
Мы начали с С# и Vb.net, затем добавили Java. Теперь C уже поддерживается, а затем хорошо фокусируется на С++, Objective-C и JavaScript, в зависимости от вашего обратная связь
Ответ 3
В то время как 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]()
Ответ 4
Похоже, вас заинтересует алгоритм Bram Cohen (BitTorrent Creator) Patience Diff (который используется в системе контроля версий на базаре).
См. Проблема diff была решена и особенно Преимущества Diff Преимущества:
Выдержка из второй ссылки:
Еще одно преимущество терпения diff заключается в том, что он часто не соответствует строкам, которые просто не должны совпадать. Например, если вы полностью переписали раздел кода, он не должен соответствовать пустым строкам в каждой версии, как показано в примере . Наконец, вот этот пример:
void func1() {
x += 1
}
+void functhreehalves() {
+ x += 1.5
+}
+
void func2() {
x += 2
}
Это просто и понятно, но часто алгоритмы diff интерпретируют это следующим образом:
void func1() {
x += 1
+}
+
+void functhreehalves() {
+ x += 1.5
}
void func2() {
x += 2
}
Ответ 5
Смотрите наши SmartDifferencer инструменты.
SmartDifferencers являются специфичными для языка, основаны на парсерах языка качества продукции, строят АСТ и сравнивают деревья. Это делает их полностью независимыми от текстового макета и промежуточных комментариев; замечательно, что они невосприимчивы к изменениям в тексте литералов (радиус, перемещение десятичной точки + показатель экспоненты, различные escape-последовательности), если фактическое значение, представленное литералом, не отличается. Результат сообщается в терминах синтаксиса языка и правдоподобных действиях редактирования (перемещение, копирование, вставка, удаление, переименование-идентификатор внутри блока).
Существуют версии для С#, Java, С++, Python и других языков. На каждом из них есть примеры каждого из них.
Для C существует SmartDifferencer, но разбор C файлов без полной командной строки компилятора иногда проблематичен, поэтому иногда он терпит неудачу, и вам приходится возвращаться к более примитивным инструментам сравнения, например diff. Мы работаем над улучшением этой ситуации.
Ответ 6
Посмотрите Сравнить ++.
Он может выполнять структурированное сравнение языков для C/С++, Java, С#, Javascript, CSS,...
и необязательно игнорировать комментарии, чистые форматированные, белые пробелы и изменения в случае и имеют уникальную возможность выравнивать перемещенные разделы, такие как функция С++, пространство имен Java, метод С#, селектор CSS,...
Ответ 7
Если вы используете eclipse, встроенный редактор сравнения предоставляет синтаксис diff/merge, по крайней мере для Java. В разделе "Общие/Сравнить/Патч" выберите "Открыть структуру сравнения автоматически", затем выберите "Сравнение структуры Java" в редакторе сравнения.
Ответ 8
Посмотрите https://en.wikipedia.org/wiki/Comparison_of_file_comparison_tools, особенно столбец Структурированное сравнение.
В настоящее время существуют только два инструмента, которые понимают структуру языка.
- Сравнить ++ (отлично работает для С++)
- Pretty Diff (инструмент сравнения кода на языке для нескольких веб-языков, а также украшает, минимизирует и некоторые другие вещи..)
К сожалению, у многих инструментов этот столбец все еще пуст.