Как отслеживает ли история Git во время рефакторинга?

Я хорошо понимаю, как Git может поддерживать перемещения файлов: поскольку он использует хэш файла, «добавленный» файл легко определяется как «удаленный».

Мой вопрос касается рефакторинга: учитывая Java, Объявление пакета изменяется, поэтому содержимое файла НЕ будет одинаковым. В таком случае, как Git определяет, что «добавленный» файл делится историей с «удаленным»? Проверяет ли «наиболее похожий контент», предполагая, что я внес только незначительные изменения или подобное недетерминированное решение?

17
задан Nicolas De loof 19 August 2010 в 08:38
поделиться

1 ответ

Как упоминается в Git FAQ, он обнаруживает похожее содержимое на основе эвристики.

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

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

Однако это не означает, что Git не поддерживает переименования.
Механизм diff в Git'е поддерживает автоматическое обнаружение переименований, это включается переключателем '-M' в семействе команд git-diff-*.
Механизм обнаружения переименований используется git-log(1) и git-whatchanged(1), поэтому, например, 'git log -M' выдаст историю коммитов с информацией о переименованиях.
Git также поддерживает ограниченную форму слияния переименований.
Два инструмента для назначения виновных, git-blame(1) и git-annotate(1), используют код автоматического обнаружения переименований для отслеживания переименований.


git log даёт некоторые подробности об этой эвристике:

-B[<n>][/<m>]

Разбейте полные изменения перезаписи на пары delete и create. Это служит двум целям:

  • Это влияет на то, как изменение, представляющее собой полную перезапись файла, будет выглядеть не как серия удалений и вставок, смешанных вместе с очень немногими строками, которые случайно совпадают по тексту в качестве контекста, а как одно удаление всего старого и одна вставка всего нового, и число m управляет этим аспектом опции -B (по умолчанию 60%).
    -B/70% указывает, что менее 30% оригинала должно остаться в результате, чтобы git считал его полной переработкой (т.е. иначе результирующий патч будет представлять собой серию удалений и вставок вперемешку с контекстными строками).

  • При использовании с -M полностью переписанный файл также рассматривается как источник переименования (обычно -M рассматривает только исчезнувший файл как источник переименования), и число n управляет этим аспектом опции -B (по умолчанию 50%).
    -B20% указывает, что изменения с добавлением и удалением, составляющие 20% или более от размера файла, могут быть приняты в качестве возможного источника переименования другого файла.

-M[<n>]

При генерации диффов обнаруживайте и сообщайте о переименованиях для каждого коммита. Для отслеживания переименований файлов при просмотре истории смотрите --follow.
Если указано n, то это порог индекса сходства (т.е. количество добавлений/удалений по сравнению с размером файла).
Например, -M90% означает, что git должен рассматривать пару удаление/добавление как переименование, если более 90% файла не изменилось.


Дополнительные ссылки:


Примечание: В Git 2.18 (Q2 2018) git status теперь должен показывать переименования (вместо удаления/добавления файлов) при перемещении/переименовании файлов.
См. "Как сказать Git'у, что это тот же каталог, только с другим именем".

20
ответ дан 30 November 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: