Что такое `git diff -patience`?

Как алгоритм терпения отличается от алгоритма git diff по умолчанию, и когда я хочу его использовать?

Ответ 1

Вы можете прочитать сообщение от Bram Cohen, автора алгоритма ограничения терпения, но я нашел этот пост в блоге, чтобы очень хорошо обобщить алгоритм анализа терпения:

Терпение Diff вместо этого фокусирует свою энергию на низкочастотных линиях с высоким содержанием, которые служат в качестве маркеров или сигнатур важного контента в тексте. Это по-прежнему основанный на LCS diff в своем ядре, но с существенным отличием, поскольку он рассматривает только самую длинную общую подпоследовательность линий подписи:

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

Когда вы должны использовать терпение diff? Согласно Брэму, терпение diff хорошо для этой ситуации:

Действительно плохие случаи - это те, где две версии расходились резко, и разработчик не проявляет осторожности, чтобы сохранить размеры патча под контролем. В этих условиях алгоритм диффе- ренции может иногда становятся "несогласованными" тем, что они соответствуют длинным участкам фигурных скобок вместе, но оно завершает корреляцию фигурных скобок функций в одна версия с фигурными скобками следующей более поздней функции в другой версия. Эта ситуация очень уродлива и может привести к непригодный конфликтный файл в ситуации, когда вам нужны такие вещи представлены согласованно больше всего.

Ответ 2

Вы также можете использовать его для слияний (отлично работает здесь для некоторых конфликтов XML):

git merge --strategy-option=patience ...

Ответ 3

Алгоритм ограничения терпения - это алгоритм медленного разложения, который в некоторых случаях показывает лучшие результаты.

Предположим, что у вас есть следующий файл, указанный в git:

.foo1 {
    margin: 0;
}

.bar {
    margin: 0;
}

Теперь мы переупорядочиваем разделы и добавляем новую строку:

.bar {
    margin: 0;
}

.foo1 {
    margin: 0;
    color: green;
}

По умолчанию алгоритм diff утверждает, что заголовки разделов изменились:

$ git diff --diff-algorithm=myers   
diff --git a/example.css b/example.css
index 7f1bd1e..6a64c6f 100755
--- a/example.css
+++ b/example.css
@@ -1,7 +1,8 @@
-.foo1 {
+.bar {
     margin: 0;
 }

-.bar {
+.foo1 {
     margin: 0;
+    color: green;
 }

В то время как анализ терпения показывает результат, который может быть более интуитивным:

$ git diff --diff-algorithm=patience
diff --git a/example.css b/example.css
index 7f1bd1e..6a64c6f 100755
--- a/example.css
+++ b/example.css
@@ -1,7 +1,8 @@
-.foo1 {
-    margin: 0;
-}
-
 .bar {
     margin: 0;
 }
+
+.foo1 {
+    margin: 0;
+    color: green;
+}

Здесь хорошее обсуждение субъективного качества diff здесь, и git 2.11 дополнительно исследует различные эвристики.

Обратите внимание, что алгоритм терпения по-прежнему имеет некоторые известные патологические случаи.