有人可以解释一下git如何在内部知道文件X,Y和Z已经改变了吗?在文件尚未添加或修改时识别的幕后流程是什么?我问,因为使用Subversion很容易弄清楚它通过在每个文件夹下有一个.svn
目录来跟踪这些事情,但对于git我似乎无法找到对此内部工作的描述。我怀疑它扫描所有子目录的变化,因为它非常快。
所以,如果好奇,它的内部运作是什么?
答案 0 :(得分:14)
确定文件状态的机制非常简单。要知道已经暂存了哪些文件,只需使用索引来区分HEAD
树。任何仅在索引中显示的项目都已暂存以供添加,仅HEAD
中显示的任何项目已被删除,并且任何不同的项目都已进行了更改。
类似地,可以通过使用工作目录区分索引来检测未分级的更改。
您的问题特别询问如何这么快(毕竟,计算文件的SHA1哈希并不是非常快。)这是索引 - 也称为缓存的地方 - 进来再玩。该指数也has fields for the file size and file modification time。因此,可以简单地stat(2)
磁盘上的文件,并与索引的文件大小和文件修改时间进行比较,以了解是否散列文件。
答案 1 :(得分:5)
您可以在第Git Internals章
上的免费书籍Pro-Git中找到答案本章解释了git如何在幕后工作。
正如Leo所说,git会检查文件的SHA1以查看它是否已更改 你可以这样检查(取自Git Internals):
$ echo 'version 1' > test.txt
$ git hash-object -w test.txt
83baae61804e65cc73a7201a7252750c76066a30
然后,将一些新内容写入文件,然后再次保存:
$ echo 'version 2' > test.txt
$ git hash-object -w test.txt
1f7a7a472abf3dd9643fd615f6da379c4acb3e3a
答案 2 :(得分:3)
如果可能重复的答案不够,您可能需要查看此http://www.geekgumbo.com/2011/07/19/git-basics-how-git-saves-your-work/
简而言之,Git使用文件内容的SHA-1
来跟踪更改。 Git跟踪四个对象:blob,树,提交和标记。
要回答您关于如何跟踪更改的问题,请点击该链接的引用:
树对象是Git如何跟踪文件名和目录。每个目录都有一个树对象。树对象指向提交时SHA-1 blob,该目录中的文件以及其他树,子目录。每个树对象都被加密到,你猜对了,它的内容的SHA-1哈希,并存储在.git / objects中。树的名称,因为它们是SHA-1哈希,允许Git通过将名称与先前的名称进行比较,快速查看是否对任何文件或目录进行了任何更改。很漂亮。
答案 3 :(得分:2)
我发现以下解释在最近的课程(Kevin Skoglund的Git基础培训)中很有用,我在Lynda.com上关注。
Git通过对已提交的更改运行算法来生成由40个十六进制字符组成的哈希密钥。例如,如果我们在不同的情况下提交了相同的更改集,那么我们应该获得相同的哈希键。
此外,它通过在每次提交中保留后续的元信息来跟踪先前的更改。
每个后续提交都将引用父提交,而第一次提交将没有父提交(或null / nil值)。下图在这方面将很有帮助。
Image credit : Git Essential Training by Kevin Skoglund at Lynda.com
答案 4 :(得分:1)
https://codewords.recurse.com/issues/two/git-from-the-inside-out
Git建立在图表上。几乎每个Git命令都会操纵它 图形。要深入理解Git,请关注它的属性 图表,而不是工作流程或命令。
用户将
data/number.txt
的内容设置为2
。这更新了 工作副本,但保留索引和HEAD
提交。用户将文件添加到Git。这会添加一个包含2的blob 对象目录。它指向
data/number.txt
的索引条目 新的blob。
答案 5 :(得分:0)
这是一个很好的参考:A Visual Git Reference - marklodato.github.io/visual-git-guide/index-en.html .由于它在信息图表的帮助下进行了演练,因此将有助于更好地理解 git。