Git всегда обнаруживает переименования «после факта», сравнивая эти два дерева (или одно дерево и индекс, для случаев, которые не включают в себя git merge
). (Линус Торвальдс считает эту особенность, например, this SO question).
В любом случае git merge
будет запускать внутренний diff git с включенным определением слияния и значением по умолчанию для сходства по умолчанию 50%, если вы не настроите его иначе. Аналогичным образом, git diff
имеет некоторые значения по умолчанию, которые также настраиваются. Если вы запустили git diff --find-renames -M50%
вручную между базой слияния и восходящим потоком, вы, вероятно, хорошо (но см. Сноску 1 о настройке).
Если git не обнаруживает переименование, вам может потребоваться настроить пороговые значения переименования и/или увеличить количество файлов, которые git должен учитывать. Первым из них является значение rename-threshold
в параметрах -X
(rename-threshold
впервые появилось в git 1.7.4). См. the documentation.
Вы можете установить merge.renameLimit
количество файлов рассматривать с точкой зрения обнаружения переименования. Если вы не установите его, текущим значением по умолчанию является 1000 файлов (но со временем значение по умолчанию изменилось). Кроме того, если вы не установите его, merge использует diff.renameLimit
, поэтому вы можете установить только второе из них, и оба параметра diff и merge используют оба значения.
Способ работы по обнаружению переименования файлов немного сложный, но достаточно простой для описания на примере. Предположим, что git сравнивает фиксацию 12345
с фиксацией 67890
, а в 12345
- файлы с путями A
, B/C
и D
; но в 67890
есть пути B/gronk
, B/C
и D
. Это означает, что путь A
ушел, но появился новый путь B/gronk
.Затем Git запоминает такие пути (вплоть до предельного значения переименования) и сравнивает содержимое 12345:A
с содержимым 67890:B/gronk
. Если файлы «достаточно схожи», git объявит, что 12345:A
был переименован в 67890:B/gronk
.
Я не уверен точно, как git решает, что файл 50%, или 75%, или что-то еще, похожее/другое. Я видел, что индекс подобия основан на «кусках», а не на линиях (хотя обычный выходной поток - линейно-ориентированный).
У вас возникают конфликты при слиянии? Обычно Git достаточно умен, чтобы понять, что файл перемещен. Что произойдет, если вы просто запустите 'git merge origin/master' (или что бы вы ни называли свою ветвь вверх)? – knittl