本地分支的文件存放在哪里

Where are files for local branches stored

I 运行 I 今天做了一件有趣的事情,这让我想知道 git 如何处理本地 b运行ches。所以我 运行 在我的存储库中遇到了一些问题并删除了本地文件夹(进入回收站)并重新克隆。(可能是极端的)在我意识到我删除了一个本地 b运行ch 之后我从不推动,因为这是个人的副项目。我惊慌了片刻,决定从回收站恢复文件夹并将其放在不同的位置,看看我是否可以取回我处理过的几个文件并将其推送到远程。起初我只是尝试使用文件资源管理器搜索找不到文件(我很伤心)然后我记得我在删除之前在另一个 b运行ch 中所以我将 gitbash 重定向到项目旧仓库的新位置和 'git branch' 看到我所有的旧 b运行ches 出现(git 魔法 #1)。所以我检查了有问题的 b运行ch,文件浏览器恰好打开到我期望文件所在的位置,然后看到文件神奇地出现了(git magic #2)

这让我想知道 git 在哪里存储本地 b运行ches 的所有数据。我知道有一个隐藏文件夹,但我在该文件夹中搜索了该文件,但没有显示它是否在其中进行了压缩和重命名?

项目根目录下有一个隐藏文件夹.git(当你运行git init或初始化一个仓库时创建),其中git存储所有 "magical bits"。这不是非常神奇 - 有一个 HEAD 文本文件说明 "head" 所在的位置(例如当前签出的分支或提交),还有 refs 目录,其中包含更多目录,其中包含对应于您的本地和远程分支名称 - 这些文件中的每一个都只是一个带有提交 SHA 的文本文件(就像一本字典,当您说 "check out master branch!" git 时会去寻找相应的文件,阅读提交的内容是 - 并检查该提交)。

提交参考 "objects",方便地在 objects/ 目录中。该目录实际上包含更多具有两个字母名称的目录 - 这是前两个字母 SHA 哈希 - 与目录内的文件名一起构成完整的哈希(提交,树或 blob)。在那个两个字母的目录中,有实际的 "objects"(git 魔法!)。对象可以是 "blob" 或 "tree" 类型,前者对应于文件,后者(松散地)对应于目录。阅读 docs 中的 git 个对象 - 这是一本简单的读物,还为您提供了一些查看单个对象的工具。

因此,如果在 .git/refs/heads/master 中是一个内容为 a2789da8f918ef26c90e51d05de5723e5ad543a4 的文本文件 - 这意味着 master 在该提交中。该提交的项目的 "state" 存储在 .git/objects/a2/789da8f918ef26c90e51d05de5723e5ad543a4 - 这是项目目录的树对象,列出了当时项目目录中所有文件和目录的 SHA。

因此,您无法真正四处浏览并找到来自不同分支的实际文件 - git 不会以这种方式考虑事物,它将事物视为文件和目录列表。当您更改文件并提交它时,它会为该文件的内容创建一个新的 "object",并为父目录创建一个新的树对象(更新文件的 SHA 更新)并写入一个提交对象(树对象列出所有项目目录中的文件和文件夹)。或者至少这是我的理解,或多或少。

希望这有助于揭开它的神秘面纱!


2017-12-21 编辑:根据@Herman 的评论更新了我的旧答案。对于它的价值,这里的这个答案可能有点"too much information without enough context"。

较短的答案 - git 将所有数据存储在项目根目录的 .git 目录中,它存储对项目文件夹状态的引用,而不是文件的单独副本。

为了后代,如果将来有人偶然发现这个答案 - 我强烈推荐这门课程:

https://app.pluralsight.com/library/courses/how-git-works/table-of-contents (您可以找到 pluralsight 的免费试用优惠,并从您的试用中获得很多价值)。