我是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中吗?
答案 0 :(得分:4)
这些问题在别处得到了解决,但是我会继续在这里做一个简短的 1 一体化答案:
refspec - 据我所知,将服务器分支映射到" local"目的地分支机构
这是效果,而不是定义。
refspec的定义只是一对引用名称,以冒号:
分隔,并带有可选的前导加号+
。冒号左侧的引用名称是 source ,右侧的名称是 destination 。如果存在前导加号,则refspec表示Git应该执行强制更新"即使它不是快进(分支引用)或自然更新引用不允许(标签)。
Refspecs用于git fetch
和git push
。省略其中一个部分在不同的命令中具有不同的效果,因此最简单的方法是使用双面都完整的refspec。当与git fetch
一起使用时,源确实是服务器的引用(通常是分支名称,但您可以复制标签,注释或服务器公开的任何其他引用 - 并且默认情况下,服务器公开所有内容)。正如您所推测的那样,目的地是您自己的本地引用,通常也是分支名称。
你的第一个问题:
A)它们是否存储在.git / refs / remotes / origin /(branches)?
默认情况下,是的。但请注意几个警告:
.git
目录,请使用git rev-parse --show-toplevel
或git rev-parse --show-cdup
,以防您在子目录中。git rev-parse
,git symbolic-ref
和git 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是具体的。了解操作实际在做什么,它们的关键不是实现一些抽象。