Русский ▾ Topics ▾ Latest version ▾ git-range-diff last updated in 2.52.0

НАЗВАНИЕ

git-range-diff - Сравнить два диапазона коммитов (например, две версии ветки)

ОБЗОР

git range-diff [--color=[<когда>]] [--no-color] [<параметры-сравнения>]
	[--no-dual-color] [--creation-factor=<фактор>]
	[--left-only | --right-only] [--diff-merges=<формат>]
	[--remerge-diff]
	( <диапазон1> <диапазон2> | <ред1>…​<ред2> | <основа> <ред1> <ред2> )
	[[--] <путь>…​]

ОПИСАНИЕ

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

При наличии аргументов <путь> эти диапазоны коммитов будут соответствующим образом ограничены.

Для этого команда сначала находит пары коммитов из обоих диапазонов коммитов, которые соответствуют друг другу. Считается, что два коммита соответствуют, когда разница между их патчами (т.е. информация об авторе, сообщениями и списками изменений коммитов) достаточно мала по сравнению с размером патчей. Подробности см. в разделе “Алгоритм” ниже.

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

Существует три способа указания диапазонов коммитов:

  • <диапазон1> <диапазон2>: Любой диапазон коммитов может иметь вид <база>..<редакция>, <редакция>^! или <редакция>^-<n>. Более подробную информацию см. в разделе УКАЗАНИЕ ДИАПАЗОНОВ в gitrevisions[7].

  • <редакция1>...<редакция2>. Это эквивалентно <редакция2>..<редакция1> <редакция1>..<редакция2>.

  • <база> <редакция1> <редакция2>: Это эквивалентно <база>..<редакция1> <база>..<редакция2>.

ПАРАМЕТРЫ

--no-dual-color

Когда списки изменений коммитов различаются, git range-diff воссоздаёт цветовую схему исходных списков сравнений и добавляет к ним внешние маркеры -/+ с красным/зелёным фоном, чтобы было легче заметить изменения, например, в том, какие именно строки были добавлены.

Кроме того, строки списков изменений коммитов, которые присутствуют только в первом диапазоне коммитов, показываются «затемнёнными» (это можно переопределить с помощью переменной конфигурации color.diff.<слот>, где <слот> — одно из contextDimmed, oldDimmed и newDimmed), а строки списков изменений, которые присутствуют только во втором диапазоне коммитов, показываются жирным шрифтом (это можно переопределить с помощью переменной конфигурации color.diff.<слот>, где <слот> — одно из contextBold, oldBold или newBold).

В range-diff это известно как «двойная раскраска». Используйте --no-dual-color, чтобы вернуться к раскраске всех строк в соответствии с внешними маркерами сравнения (и полностью игнорировать внутреннее содержимое списков изменений при раскраске).

--creation-factor=<процент>

Установить фактор корректировки стоимости создания/удаления в значение <процент>. По умолчанию 60. Попробуйте большее значение, если git range-diff ошибочно принимает большое изменение за полную перезапись (удаление одного коммита и добавление другого), и меньшее значение в обратном случае. Объяснение того, почему это необходимо, см. в разделе ``Алгоритм`` ниже.

--left-only

Подавлять коммиты, отсутствующие в первом указанном диапазоне (или «левом диапазоне» при использовании формата <редакция1>...<редакция2>).

--right-only

Подавлять коммиты, отсутствующие во втором указанном диапазоне (или «правом диапазоне» при использовании формата <редакция1>...<редакция2>).

--diff-merges=<формат>

Вместо игнорирования коммитов слияния генерировать для них сравнения, используя соответствующий параметр --diff-merges=<формат> команды git-log[1], и включать их в сравнение.

Примечание: обычно режим remerge будет наиболее естественным вариантом, поскольку он показывает только сравнение поверх того, что произвёл бы механизм слияния самого Git. Другими словами, если коммит слияния является результатом git merge, который завершился без конфликтов, то режим remerge будет представлять его, как содержащий пустой список изменений.

--remerge-diff

Параметр для удобства, эквивалентен --diff-merges=remerge.

--notes[=<ссылка>]
--no-notes

Этот флаг передаётся программе git log (см. git-log[1]), которая генерирует патчи.

<диапазон1> <диапазон2>

Сравнивает коммиты, указанные двумя диапазонами, где <диапазон1> считается более старой версией, чем <диапазон2>.

<редакция1>…​<редакция2>

Эквивалентно передаче <редакция2>..<редакция1> и <редакция1>..<редакция2>.

<база> <редакция1> <редакция2>

Эквивалентно передаче <база>..<редакция1> и <база>..<редакция2>. Обратите внимание, что <база> не обязательно должна быть точной точкой ветвления. Пример: после перебазирования ветки my-topic команда git range-diff my-topic@{u} my-topic@{1} my-topic покажет различия, внесённые перебазированием.

git range-diff также принимает обычные параметры сравнения (см. git-diff[1]), наиболее примечательными из которых являются параметры --color=[<когда>] и --no-color. Эти параметры используются при создании «сравнений между патчами», т.е. для сравнения авторов, сообщений и списков изменний соответствующих старых/новых коммитов. Возможности настроить большинство параметров сравнения, передаваемых в git log при создании этих патчей, в настоящее время нет.

СТАБИЛЬНОСТЬ ВЫВОДА

Вывод команды range-diff может изменяться. Он предназначен для человекочитаемого «фарфорового» вывода, так что не стоит ожидать, что range-diff будет текстуально стабильным между разными версиями Git (в отличие от, например, параметра --stable команды git-patch-id[1]). Также для range-diff нет эквивалента git-apply[1], так как вывод не предназначен для машинного чтения.

В частности это особенно важно при использовании параметров сравнения. В настоящее время некоторые параметры, такие как --stat, могут в качестве эмерджентного эффекта создавать вывод, который совершенно бесполезен в контексте range-diff. Будущие версии range-diff могут научиться интерпретировать такие параметры способом, специфичным для range-diff (например, --stat мог бы создавать человекочитаемую сводку того, как изменилась статистика изменений).

КОНФИГУРАЦИЯ

Эта команда использует настройки diff.color.* и pager.range-diff (последняя включена по умолчанию). См. git-config[1].

ПРИМЕРЫ

В случае если при перебазировании потребовалось разрешать конфликты слияния, непосредственно после него сравните изменения, внесённые в процессе перебазирования, с помощью:

$ git range-diff @{u} @{1} @

Типовой вывод git range-diff выглядит так:

-:  ------- > 1:  0ddba11 Подготовка к неизбежному!
1:  c0debee = 2:  cab005e Добавление полезного сообщения в начале
2:  f00dbal ! 3:  decafe1 Описание бага
    @@ -1,3 +1,3 @@
     Author: A U Thor <author@example.com>

    -TODO: Описать баг
    +Описать баг
    @@ -324,5 +324,6
      Это было ожидаемо.

    -+Неожиданным было то, что он ещё и упадёт.
    ++Но неожиданно, что он к тому же падает. Это баг и присяжные заседатели всё
    ++ещё совещаются, как его лучше пофиксить. См. подробности в тикете #314.

      Для связи:
3:  bedead < -:  ------- ОТКАТИ МЕНЯ

В этом примере в старой и новой версиях по 3 коммита, причём разработчик добавил новый коммит в начало, изменил сообщение, а также его содержимое 2-го и удалил 3-й.

Когда вывод направляется на терминал, он по умолчанию раскрашен, как и обычный вывод git diff. Кроме того, первая строка (добавление коммита) зелёная, последняя строка (удаление коммита) красная, вторая строка (с идеальным совпадением) жёлтая, как заголовок коммита в выводе git show; третья строка также окрашивает старый коммит в красный, новый — в зелёный, а остальное — как заголовок коммита git show.

Однако наивная раскраска списка изменений на самом деле немного трудно читается, так как она окрашивает целые строки в красный или зелёный цвета. Например, строка, которая добавила «Неожиданным было то, что…​» в старом коммите, полностью красная, даже если целью старого коммита было что-то добавить.

Для большей наглядности, range по умолчанию использует режим --dual-color. В этом режиме сравнение списков изменений сохраняет их исходные цвета и добавляет к строкам маркеры -/+ с красным или зелёным фоном, чтобы было легче видеть, что они описывают, как изменился сам список изменений.

Алгоритм

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

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

Чтобы избежать ложных срабатываний (например, когда патч был удалён, а несвязанный патч был добавлен между двумя итерациями одной и той же серии патчей), чтобы учесть это матрица стоимости расширяется путём добавления записей с фиксированной стоимостью для удалений/добавлений целых коммитов.

Пример: Пусть коммиты 1--2 будут первой итерацией серии патчей, а A--C — второй. Предположим, что A — это копия 2, а C — это копия 1, но с небольшим изменением (скажем, исправлена опечатка). Представьте коммиты в виде двудольного графа:

    1            A

    2            B

		 C

Мы ищем «лучшее» объяснение новой серии в терминах старой. Мы можем представить «объяснение» как ребро в графе:

    1            A
	       /
    2 --------'  B

		 C

Это объяснение стоит «бесплатно», потому что изменений не было. Аналогично C можно объяснить с помощью 1, но это имеет некоторую стоимость c>0 из-за изменений:

    1 ----.      A
	  |    /
    2 ----+---'  B
	  |
	  `----- C
	  c>0

В математических терминах мы ищем нечто вроде минимального по стоимости двудольного сопоставления; 1 сопоставляется с C с некоторой стоимостью и т.д. Базовый граф на самом деле является полным двудольным графом; стоимость, которую мы связываем с каждым ребром, — это размер сравнения между патчами двух коммитов. Чтобы также объяснить новые коммиты, мы вводим фиктивные узлы с обеих сторон:

    1 ----.      A
	  |    /
    2 ----+---'  B
	  |
    o     `----- C
	  c>0
    o            o

    o            o

Стоимость ребра o--C — это размер сравнения C, изменённая на фактор корректировки, который должен быть меньше 100%. Стоимость ребра o--o равна нулю. Фактор корректировки необходим, потому что даже если 1 и C не имеют по сути ничего общего, каждый из них всё равно может иметь несколько пустых строк и тому подобное, что, возможно, сделает сопоставление 1--C, o--o немного дешевле, чем 1--o, o--C, даже если 1 и C не имеют ничего общего. С фактором корректировки мы требуем, чтобы гораздо большая часть была общей, чтобы патчи считались соответствующими друг другу.

Общее время, необходимое для вычисления этого алгоритма, складывается из времени, необходимого для вычисления n+m списков изменений коммитов, а затем n*m сравнений патчей, плюс время, необходимое для вычисления назначений с наименьшей стоимостью между n и m сравнениями. Git использует реализацию алгоритма Джонкера-Волгенанта для решения задачи о назначениях, который имеет кубическую временную сложность. Найденное в этом случае сопоставление будет выглядеть так:

    1 ----.      A
	  |    /
    2 ----+---'  B
       .--+-----'
    o -'  `----- C
	  c>0
    o ---------- o

    o ---------- o

СМ. ТАКЖЕ

GIT

Является частью пакета git[1]