有好几次,我遇到过这样的说法,如果你将一个函数从一个文件移动到另一个文件,Git 可以跟踪它。例如,这个条目说,“Linus 说如果你将一个函数从一个文件移动到另一个文件,Git 会告诉你这个移动过程中单个函数的历史。”
但是我对 Git 的一些底层设计有一点了解,我不明白这是怎么可能的。所以我想知道......这是一个正确的说法吗?如果是这样,这怎么可能?
我的理解是,Git 将每个文件的内容存储为一个 Blob,每个 Blob 都有一个全局唯一标识,该标识来自其内容和大小的 SHA 哈希值。然后 Git 将文件夹表示为树。任何文件名信息都属于树,而不属于 Blob,因此文件重命名例如显示为对树的更改,而不是对 Blob。
因此,如果我有一个名为“foo”的文件,其中包含 20 个函数,以及一个名为“bar”的文件,其中包含 5 个函数,然后我将其中一个函数从 foo 移动到 bar(分别导致 19 和 6), Git 如何检测到我将该函数从一个文件移动到另一个文件?
据我了解,这将导致存在 2 个新 blob(一个用于修改后的 foo,一个用于修改后的 bar)。我意识到可以计算出一个差异来表明该函数已从一个文件移动到另一个文件。但是我看不到有关该函数的历史记录如何可能与 bar 而不是 foo 相关联(无论如何都不会自动关联)。
如果 Git 要实际查看单个文件的内部,并为每个函数计算一个 blob(这将是疯狂的/不可行的,因为您必须知道如何解析任何可能的语言),那么我可以看到这是如何可能的。
所以……这个说法正确与否?如果它是正确的,那么我的理解中缺少什么?