Википедия объясняет автоматическое определение переименования:
Вкратце, учитывая файл в редакции N, файл с тем же именем в редакции N-1 является его предком по умолчанию. Однако, когда в ревизии N-1 нет файла с таким же именем, Git ищет файл, который существовал только в ревизии N-1 и очень похож на новый файл.
Обнаружение переименования, по-видимому, сводится к обнаружению аналогичных файлов. Этот алгоритм где-нибудь задокументирован? Было бы неплохо узнать, какие преобразования обнаруживаются автоматически.
Ответы:
Git отслеживает содержимое файла, а не имена файлов. Таким образом, git легко обнаружит переименование файла без изменения его содержимого. (Git не отслеживает, но выполняет обнаружение ; использование
git mv
илиgit rm
иgit add
фактически одно и то же.)Когда файл добавляется в репозиторий, имя файла находится в объекте дерева. Фактическое содержимое файла добавляется в репозиторий в виде большого двоичного объекта ( blob ). Git не будет добавлять еще один большой двоичный объект для дополнительных файлов с таким же содержимым. Фактически, Git не может, поскольку содержимое хранится в файловой системе, причем первые два символа хеша являются именем каталога, а остальные - именем файла в нем. Итак, чтобы обнаружить переименования, нужно сравнить хеши.
Чтобы обнаружить небольшие изменения в переименованном файле, Git использует определенные алгоритмы и пороговое значение, чтобы увидеть, является ли это переименованием. Например, посмотрите на
-M
флаг дляgit diff
. Существуют также значения конфигурации, такие какmerge.renameLimit
(количество файлов, которые следует учитывать при выполнении обнаружения переименования во время слияния).Чтобы понять, как git обрабатывает похожие файлы (т. Е. Какие преобразования файлов считаются переименованием), изучите доступные параметры конфигурации и флаги, как упоминалось выше. Не нужно думать о том, как. Чтобы понять, как git на самом деле выполняет эти задачи, просмотрите алгоритмы поиска различий в тексте и прочтите исходный код git.
Алгоритмы применяются только для целей сравнения, слияния и ведения журнала - они не влияют на то, как git их хранит. Любое небольшое изменение содержимого файла означает, что для него добавляется новый объект. На этом уровне не происходит никаких дельт или различий. Конечно, позже объекты могут быть упакованы там, где дельты хранятся в файлах пакетов, но это не связано с обнаружением переименования.
источник
Существует множество алгоритмов, которые обнаруживают сходство между текстами, и системы контроля версий часто используют их уже для хранения только разницы между двумя версиями. Такие инструменты, как WinMerge, достаточно умны, чтобы обнаруживать различия даже внутри строк, поэтому я не вижу причин, по которым эти алгоритмы не будут использоваться для этого обнаружения переименования.
Вот обсуждение алгоритмов обнаружения похожих текстов . Некоторые из этих алгоритмов могут быть оптимизированы для естественных языков, в то время как другие могут работать лучше для исходного кода, но по сути они очень похожи.
источник