git获取数据存储在哪里?

时间:2016-07-02 21:10:22

标签: git

我是git的新手,我试图理解它的概念。

refspec - 据我所知,将服务器分支映射到" local"目的地分支。

我写了#34;本地"因为如果我们做“git fetch'它们不与我们的工作副本或临时区域合并,而是保存在其他地方。

所以我的问题是

A)它们是存储在.git / refs / remotes / origin /(分支机构)吗?

B)如果是.git / refs / remotes / origin /(分支)的内容是对服务器中更改所在地的引用/ ID?

在.git / refs / remotes / origin /的一个分支中,我发现:761db53af177ecfd9c9b14511360537e041ebed7

C)当我们进行提交时,更改保存在哪里?

它们存储在.git / objects中吗?

2 个答案:

答案 0 :(得分:4)

这些问题在别处得到了解决,但是我会继续在这里做一个简短的 1 一体化答案:

  

refspec - 据我所知,将服务器分支映射到" local"目的地分支机构

这是效果,而不是定义

refspec的定义只是一对引用名称,以冒号:分隔,并带有可选的前导加号+。冒号左侧的引用名称是 source ,右侧的名称是 destination 。如果存在前导加号,则refspec表示Git应该执行强制更新"即使它不是快进(分支引用)或自然更新引用不允许(标签)。

Refspecs用于git fetchgit push。省略其中一个部分在不同的命令中具有不同的效果,因此最简单的方法是使用双面都完整的refspec。当与git fetch一起使用时,源确实是服务器的引用(通常是分支名称,但您可以复制标签,注释或服务器公开的任何其他引用 - 并且默认情况下,服务器公开所有内容)。正如您所推测的那样,目的地是您自己的本地引用,通常也是分支名称。

你的第一个问题:

  

A)它们是否存储在.git / refs / remotes / origin /(branches)?

默认情况下,是的。但请注意几个警告:

  • 要查找.git目录,请使用git rev-parse --show-toplevelgit rev-parse --show-cdup,以防您在子目录中。
  • 参考名称可能打包,在这种情况下,它们不会存储在各自的文件中。
  • Git是(内部)为可变名称开发一个可插拔的后端,所以即使上面的内容也会发生变化:要从脚本中解析或更新引用名称,你应该使用Git"管道"命令,即git rev-parsegit symbolic-refgit update-ref

"默认情况下"上面限定符的一部分是因为目标名称实际上是配置项。对于名为origin的远程,git fetch默认使用配置的remote.origin.fetch值:

$ cd [path to git repo for git]
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$ cd [path to git repo for FreeBSD]
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
+refs/notes/*:refs/notes/origin/*
$ 

如上所示,您可以为任何指定的遥控器配置多个 fetch配置。

(对于名为$rem的远程用户,请使用git config --get-all remote.$rem.fetch查看其默认提取refspec。)

如上所示,fetch refspecs可能包含通配符*个字符。这些工作很像shell(sh,bash,zsh等)" glob"字符,除了在旧版本的Git 2 中,它们被限制为在斜杠/之后立即出现(例如,refs/heads/pr*将被禁止),当然,当它们出现时在目的地方面,他们只是扩展回源头上匹配的任何内容,因此必须配对。

  

B)如果是,每个.git / refs / remotes / origin /(分支)的内容是对服务器中更改所在地的引用/ ID?

排序:它是对象标识符。 (这个问题的确切形式暗示了一个错误的假设,我们将在稍后得出。)

因为refs/remotes/origin/$branch远程跟踪分支名称(因此是refs/heads/名称空间分支名称的副本),所以它实际上必须指向< sup> 3 一个提交对象。请注意,refs/中名称的位置决定了引用类型。它是暗示对象类型的引用类型:大多数名称通常应指向提交对象,但标记名称可能指向四种基本对象类型中的任何一种。 (这四种类型是提交 blob 标记或&#34;带注释的标记&#34 ;;标签名称通常应直接指向提交,或指向带注释的标签对象。提交指向父提交和一棵树;树指向blob和其他树; blob包含文件内容。另请参阅问题C的答案。 )

  

C)当我们进行提交时,更改保存在哪里?

这是你摆脱困境的地方: Git保存快照,而不是更改。但你大部分都在正确的区域!

图片值得多说,所以我会包含a link to the Pro Git book chapter

  

它们存储在.git / objects中吗?

这是Git存储&#34;目标文件&#34;的地方。新提交意味着一个新对象,新对象进入该目录(实际文件名是复杂化的 4 ,以使Git在Linux机器上运行得更快,其中&#34; fat&#34;目录很慢)。如上所述,新提交指向一个树 - 通常是一个新的树对象,而不是一些现有的树对象 - 树提供从合理的用户文件名(和文件模式,特别是执行位)到Git blob的映射 - 对象名称。树和blob对象也存储在.git/objects

然而,使对象变得复杂,可能打包到&#34;包文件&#34;中。 (此时,Git 确实开始进行增量压缩,就像其他版本控制系统一样,但有一个显着的变化,即不需要对先前版本的&#34;完全相同的&#34;文件,甚至文件。实际上,选择delta链的启发式方法目前通过文件名和大小关联,但原则上我们可以压缩文件树,或反之亦然,如果运作良好。)

1 简写为&#34;写时间&#34;而不是&#34;答案长度&#34;。 :-)如果我花了更长的时间,我可以写一个更短的答案......

2 在Git 2.5左右的某个地方,但我没有时间查找放宽通配符放置限制的确切版本。

3 短语&#34;指向&#34;这里是&#34;的缩写,包含&#34;的ID,暗示我们或Git可以按照这个ID来查找对象本身,就好像跟着一个指向箭头一样:这样通往出口对象。

4 向非英语母语人士道歉:这不是一个真正的词,而是一个复杂的#34;和&#34;并发症&#34;用状语后缀&#34; -ify&#34;添加两次胶水,锉削和打磨以适应,只是为了使并发症复杂化。 : - )

答案 1 :(得分:0)

首先考虑提交历史,然后考虑所有提交历史。 git中的所有东西都减少了提交名称和它们的祖先。你看到的每个refname,你要做的第一件事就是将它转换为一个提交id,因为这就是git所做的。 git中的所有内容都存储在对象db中。 “暂存区域”并不存在,它是对象db中的事物的概念状态(事物“git add”ed to it,或者被提取到它中,或者在某些时候被推入它)和索引。它们可能尚未被实际提交引用。不管。不要挂在抽象上,git是具体的。了解操作实际在做什么,它们的关键不是实现一些抽象。