Несколько раз я сталкивался с утверждением, что если вы перемещаете одну функцию из одного файла в другой файл, Git может отслеживать ее. Например, эта запись говорит: "Линус говорит, что если вы переместите функцию из одного файла в другой, Git сообщит вам историю этой единственной функции через двигаться".
Но у меня есть немного понимания некоторых из Git дизайна под капотом, и я не вижу, как это возможно. Так что мне интересно... это правильное утверждение? И если да, то как это возможно?
Мое понимание заключается в том, что Git хранит каждое содержимое файла как Blob, и каждый Blob имеет уникальную глобальную идентификацию, которая возникает из хэша SHA его содержимого и размера. Git затем представляет папки как деревья. Любая информация о имени файла принадлежит дереву, а не к Blob, поэтому переименование файла, например, отображается как изменение дерева, а не в Blob.
Итак, если у меня есть файл с именем "foo" с 20 функциями в нем и файл под названием "bar" с 5 функциями в нем, и я перехожу одну из функций из foo в bar (в результате получается 19 и 6, соответственно), как Git обнаружить, что я переместил эту функцию из одного файла в другой?
По моему мнению, это приведет к появлению 2 новых blobs (один для измененного foo и один для модифицированного бара). Я понимаю, что diff можно рассчитать, чтобы показать, что функция была перенесена из одного файла в другой. Но я не вижу, как история о функции может стать ассоциированной с баром, а не foo (не автоматически, во всяком случае).
Если Git должен был заглянуть внутрь отдельных файлов и вычислить blob для каждой функции (что было бы сумасшедшим/неосуществимым, потому что вам нужно было бы знать, как разбирать любой возможный язык), тогда я мог видеть, как это возможно.
Итак... утверждение правильное или нет? И если это правильно, то чего не хватает в моем понимании?