Как git обнаруживает похожие файлы для переименования? - PullRequest
82 голосов
/ 29 октября 2011

Википедия объясняет автоматическое обнаружение переименования:

Вкратце, приведенный файл в редакции N, файл с тем же именем в ревизия N-1 является ее предком по умолчанию. Однако, когда нет файл с одинаковым именем в ревизии N-1, Git ищет файл, который существовал только в ревизии N-1 и очень похоже на новый файл.

Обнаружение переименования, по-видимому, сводится к аналогичному обнаружению файлов. Этот алгоритм задокументирован где-нибудь? Было бы неплохо узнать, какие виды преобразований обнаруживаются автоматически.

Ответы [ 2 ]

84 голосов
/ 30 октября 2011

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 хранит их.Любое небольшое изменение содержимого файла означает, что для него добавлен новый объект.На этом уровне не происходит разницы или различий.Конечно, позже объекты могут быть упакованы там, где дельты хранятся в пакетных файлах, но это не связано с обнаружением переименования.

3 голосов
/ 29 октября 2011

Существует много алгоритмов, которые обнаруживают сходство между текстами, и системы контроля версий часто уже используют их для хранения только различий между двумя версиями. Такие инструменты, как WinMerge, достаточно умны, чтобы обнаруживать различия даже внутри линий, поэтому я не вижу причины, по которой эти алгоритмы не будут использоваться для этого обнаружения переименования.

Здесь обсуждается алгоритм для обнаружения похожих текстов . Некоторые из этих алгоритмов могут быть оптимизированы для естественных языков, в то время как другие могут лучше работать для исходного кода, но по сути они очень похожи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...