我今天跑了一件有趣的事情,这让我想知道git是如何处理本地分支的。所以我在我的存储库上遇到了一些问题,我删除了本地文件夹(回收站)并重新克隆。(也许是极端的)在我这样做之后,我意识到我删除了一个本地分支,因为这是一个个人副业,我从来没有推送过它。我惊慌失措了一阵子,决定从回收站恢复文件夹,把它放在不同的位置,看看我能不能把我处理过的几个文件拿回来,并推送到远程。起初,我只是尝试使用文件资源管理器搜索,找不到文件(我很难过),然后我记起在删除之前我在一个不同的分支中,所以我将gitbash重定向到项目旧repo的新位置,然后'git分支‘看到所有的旧分支都出现了(git魔术#1)。所以我签出了有问题的分支,文件资源管理器碰巧打开了我期望的文件所在的位置,看着文件神奇地出现了(git魔术#2)
这让我想知道git在哪里存储本地分支的所有数据。我知道有一个隐藏的文件夹,但我搜索了那个文件,它没有显示出来,它是不是在那里压缩并重命名了?
发布于 2015-11-06 05:49:28
在项目根目录中有一个隐藏的文件夹.git (它是在运行git init或初始化存储库时创建的),其中存储了所有“神奇的比特”。这并不是非常神奇-有一个HEAD文本文件,它说明了“头”在哪里(例如,当前签出的分支或提交),还有一个refs目录,其中有更多的目录,其中包含与您的本地和远程分支名称相对应的文件-这些文件中的每个文件都只是一个带有commit SHA的文本文件(就像一个字典,当您说“签出主分支!”git将去寻找相应的文件,读取提交是什么-并检查该提交)。
Commit指的是"objects",在objects/目录中很方便。该目录实际上包含了更多具有两个字母名称的目录-它们是前两个字母的SHA散列-与目录中的文件名一起构成(提交、树或blob的)完整散列。在这个由两个字母组成的目录中,有实际的“对象”(git魔术!)。对象可以是"blob“或"tree”类型,前者对应于文件,后者(松散地)对应于目录。阅读docs中的git对象-这是一个简单的阅读,也为你提供了一些工具来查看单独的对象。
因此,如果在.git/refs/heads/master中是一个内容为a2789da8f918ef26c90e51d05de5723e5ad543a4文本文件-这意味着master在提交。提交时项目“状态”存储在.git/objects/a2/789da8f918ef26c90e51d05de5723e5ad543a4中-这是项目目录的树对象,列出了当时项目目录中所有文件和目录的SHA。
所以,你不能真正地浏览并找到来自不同分支的实际文件- git不会以这种方式考虑事情,它会考虑文件和目录的列表。当您更改文件并提交它时,它会为该文件的内容创建一个新的“对象”,并为父目录创建新的树对象(为更新的文件创建更新的SHA ),并写入一个提交对象(列出项目目录中所有文件和文件夹的树对象)。或多或少,这是我的理解。
希望这有助于揭开它的神秘面纱!
2017-12-21编辑:根据@Herman的评论更新了我的旧答案。对于它的价值,这里的答案可能有点“信息太多,没有足够的上下文”。
简而言之- git将所有数据存储在项目根目录下的.git目录中,它存储对项目文件夹状态的引用,而不是文件的单独副本。
为了后人着想,如果有人在未来偶然发现了这个答案--我强烈推荐这个课程:
https://app.pluralsight.com/library/courses/how-git-works/table-of-contents (你可以找到pluralsight的免费试用优惠,并从你的试用中获得很多价值)。
https://stackoverflow.com/questions/33555221
复制相似问题