git-range-diff
Имя
git-range-diff — сравнение двух диапазонов коммитов (например, двух версий ветки)
Краткое описание
git range-diff [--color=[<when>]] [--no-color] [<diff-options>]
[--no-dual-color] [--creation-factor=<factor>]
[--left-only | --right-only] [--diff-merges=<format>]
[--remerge-diff] [--no-notes | --notes[=<ref>]]
( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> )
[[--] <path>…] Описание
Эта команда показывает различия между двумя версиями серии патчей или, в более общем случае, двумя диапазонами коммитов (коммиты слияния игнорируются).
При наличии аргументов <path> соответствующие диапазоны коммитов ограничиваются.
Для этого сначала находятся пары соответствующих друг другу коммитов из обоих диапазонов. Считается, что два коммита соответствуют друг другу, если различия между их патчами (то есть информация об авторе, сообщение коммита и его изменения) достаточно малы по сравнению с размером патчей. Подробности см. ниже в разделе Algorithm.
Затем список совпавших коммитов выводится в порядке второго диапазона коммитов, а несовпавшие коммиты вставляются сразу после вывода всех их предков.
Указать диапазоны коммитов можно тремя способами:
-
<range1> <range2>: каждый диапазон коммитов может иметь вид <base>
..<rev>, <rev>^!или <rev>^-<n>. Подробности см. в разделеSPECIFYING RANGESсправочной страницы gitrevisions[7]. -
<rev1>
...<rev2>. Эквивалентно <rev2>..<rev1> <rev1>..<rev2>. -
<base> <rev1> <rev2>: эквивалентно <base>
..<rev1> <base>..<rev2>.
Параметры
-
--no-dual-color -
Если изменения коммитов различаются,
gitrange-diffсохраняет исходную раскраску изменений и добавляет внешние маркеры различий -/+ с красным/зелёным фоном, чтобы было легче заметить, например, изменение конкретных добавленных строк.Кроме того, строки изменений коммита, присутствующие только в первом диапазоне коммитов, отображаются «приглушёнными» (это можно переопределить с помощью параметра конфигурации
color.diff.<slot>, где<slot>— одно из значенийcontextDimmed,oldDimmedиnewDimmed), а строки изменений коммита, присутствующие только во втором диапазоне коммитов, отображаются полужирным шрифтом (это можно переопределить с помощью параметров конфигурацииcolor.diff.<slot>, где<slot>— одно из значенийcontextBold,oldBoldилиnewBold).В
range-diffэто называется «двойной раскраской». Используйте--no-dual-color, чтобы вернуть раскраску всех строк согласно внешним маркерам различий (и полностью игнорировать внутренние различия при выборе цвета). -
--creation-factor=<percent> -
Задаёт поправочный коэффициент стоимости создания/удаления, равный
<percent>. По умолчанию — 60. Попробуйте увеличить значение, еслиgitrange-diffошибочно считает крупное изменение полной заменой (удалением одного коммита и добавлением другого), или уменьшить — в обратном случае. Объяснение необходимости этого параметра см. ниже в разделеAlgorithm. -
--left-only -
Не выводить коммиты, отсутствующие в первом указанном диапазоне (или в «левом диапазоне» при использовании формы <rev1>
...<rev2>). -
--right-only -
Не выводить коммиты, отсутствующие во втором указанном диапазоне (или в «правом диапазоне» при использовании формы <rev1>
...<rev2>). -
--diff-merges=<format> -
Вместо игнорирования коммитов слияния создавать для них различия, используя соответствующий параметр
--diff-merges=<format> команды git-log[1], и включать их в сравнение.Примечание. В обычном случае наиболее естественным будет режим
remerge, поскольку он показывает только различия сверх тех, которые создал бы механизм слияния Git. Иными словами, если коммит слияния является результатом слиянияgitmergeбез конфликтов, режимremergeпредставит его как пустое изменение. -
--remerge-diff -
Вспомогательный параметр, эквивалентный
--diff-merges=remerge. -
--notes[=<ref>] -
--no-notes -
Этот флаг передаётся программе
gitlog(см. git-log[1]), которая создаёт патчи. - <range1> <range2>
-
Сравнить коммиты, указанные двумя диапазонами, считая
<range1>более старой версией<range2>. -
<rev1>
...<rev2> -
Эквивалентно передаче <rev2>
..<rev1> и <rev1>..<rev2>. - <base> <rev1> <rev2>
-
Эквивалентно передаче <base>
..<rev1> и <base>..<rev2>. Обратите внимание, что<base>не обязательно должна быть точкой ветвления веток. Например, после перебазирования веткиmy-topicкомандаgitrange-diffmy-topic@{u}my-topic@{1}my-topicпокажет различия, внесённые перебазированием.
git range-diff также принимает обычные параметры diff (см. git-diff[1]), в частности параметры --color[=<when>] и --no-color. Эти параметры используются при создании «различий между патчами», то есть для сравнения автора, сообщения коммита и изменений соответствующих старых/новых коммитов. В настоящее время нет возможности настроить большинство параметров diff, передаваемых команде git log при создании этих патчей.
Стабильность вывода
Формат вывода команды range-diff может изменяться. Он предназначен для удобного чтения человеком, а не для получения текстово стабильного range-diff, совместимого между версиями Git (в отличие, например, от параметра --stable команды git-patch-id[1]). Для range-diff также нет аналога git-apply[1]: вывод не предназначен для машинного чтения.
Это особенно верно при передаче параметров diff. В настоящее время некоторые параметры, например --stat, могут в качестве побочного эффекта создавать совершенно бесполезный в контексте range-diff вывод. В будущих версиях range-diff может появиться специальная обработка таких параметров, учитывающая особенности range-diff (например, для --stat — формирование удобного для чтения сводного описания изменений статистики diff).
Настройка
Эта команда использует параметры diff.color.* и pager.range-diff (последний включён по умолчанию). См. git-config[1].
Примеры
Если при перебазировании потребовалось разрешить конфликты слияния, сравнить внесённые перебазированием изменения можно сразу после него с помощью команды:
$ git range-diff @{u} @{1} @ Типичный вывод команды git range-diff будет выглядеть так:
-: ------- > 1: 0ddba11 Prepare for the inevitable!
1: c0debee = 2: cab005e Add a helpful message at the start
2: f00dbal ! 3: decafe1 Describe a bug
@@ -1,3 +1,3 @@
Author: A U Thor <author@example.com>
-TODO: Describe a bug
+Describe a bug
@@ -324,5 +324,6
This is expected.
-+What is unexpected is that it will also crash.
++Unexpectedly, it also crashes. This is a bug, and the jury is
++still out there how to fix it best. See ticket #314 for details.
Contact
3: bedead < -: ------- TO-UNDO В этом примере есть 3 старых и 3 новых коммита: разработчик удалил третий, добавил новый перед первыми двумя и изменил сообщение второго коммита, а также его изменения.
При выводе в терминал текст по умолчанию раскрашивается, как и обычный вывод git diff. Кроме того, первая строка (добавление коммита) отображается зелёным цветом, последняя (удаление коммита) — красным, вторая (полное совпадение) — жёлтым, как заголовок коммита в выводе git show, а в третьей старый коммит выделен красным, новый — зелёным, а остальное окрашено как заголовок коммита в выводе git show.
Однако наивное раскрашенное сравнение различий довольно сложно читать, поскольку целые строки окрашиваются в красный или зелёный цвет. Например, строка, добавляющая «What is unexpected» в старом коммите, полностью окрашена красным, хотя смысл старого коммита состоял в добавлении чего-либо.
Чтобы упростить чтение, range по умолчанию использует режим --dual-color. В этом режиме сравнение различий сохраняет исходные цвета diff, а строки снабжаются маркерами -/+ с красным или зелёным фоном, чтобы было очевиднее, что они показывают изменения самого diff.
Алгоритм
Общая идея такова: мы строим матрицу стоимости для коммитов из обоих диапазонов, а затем решаем задачу о назначениях с минимальной стоимостью.
Матрица стоимости заполняется следующим образом: для каждой пары коммитов создаются оба diff, затем создаётся «diff различий» с тремя контекстными строками, после чего стоимостью считается количество строк в этом diff.
Чтобы избежать ложных совпадений (например, если патч удалили, а между двумя итерациями одной серии патчей добавили несвязанный патч), матрица стоимости расширяется: добавляются элементы с фиксированной стоимостью для полного удаления или добавления.
Пример: пусть коммиты 1--2 относятся к первой итерации серии патчей, а A--C — ко второй. Предположим, что A — это cherry-pick коммита 2,, а C — cherry-pick коммита 1 с небольшим изменением (скажем, исправлением опечатки). Представим коммиты в виде двудольного графа:
1 A
2 B
C Мы ищем «наилучшее» объяснение новой серии с точки зрения старой. «Объяснение» можно представить ребром графа:
1 A
/
2 --------' B
C Такое объяснение ничего не стоит, поскольку изменений не было. Аналогично, C можно объяснить с помощью 1, но это будет стоить c>0 из-за внесённого изменения:
1 ----. A
| /
2 ----+---' B
|
`----- C
c>0 В математических терминах мы ищем задачу о паросочетании в двудольном графе с минимальной стоимостью: 1 сопоставляется с C за некоторую стоимость и так далее. На самом деле исходный граф является полным двудольным графом; стоимость каждого ребра равна размеру diff между патчами двух коммитов. Чтобы учитывать также новые коммиты, добавим фиктивные узлы с обеих сторон:
1 ----. A
| /
2 ----+---' B
|
o `----- C
c>0
o o
o o Стоимость ребра o--C равна размеру diff для C, умноженному на поправочный коэффициент, который должен быть меньше 100%. Ребро o--o ничего не стоит. Поправочный коэффициент необходим, поскольку даже если 1 и C не имеют ничего общего, в них всё же могут совпадать несколько пустых строк и тому подобное. Из-за этого назначение 1--C, o--o может оказаться немного дешевле, чем 1--o, o--C, даже если 1 и C не имеют ничего общего. Поправочный коэффициент позволяет требовать значительно большей общности, чтобы считать патчи соответствующими.
Общее время выполнения алгоритма складывается из времени на вычисление diff для n+m коммитов, затем n*m diff между патчами и времени на поиск назначения с минимальной стоимостью между n и m diff. Для решения задачи о назначениях Git использует реализацию алгоритма Йонкера — Фолкмана с кубической временной сложностью. В данном случае найденное соответствие будет выглядеть так:
1 ----. A
| /
2 ----+---' B
.--+-----'
o -' `----- C
c>0
o ---------- o
o ---------- o См. также
сравнение диапазонов
© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/git-range-diff