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