我是 git 的新手,我正在尝试理解它的概念。
refspec - 据我所知,将服务器分支映射到“本地”目标分支。
我写了“本地”,因为如果我们执行“git fetch”,它们不会与我们的工作副本或暂存区 merge ,它们会保存在其他地方。
所以我的问题是
A) 它们是否存储在 .git/refs/remotes/origin/(branches)?
B)如果是,每个 .git/refs/remotes/origin/(branch) 的内容是服务器中更改位置的引用/ID?
在 .git/refs/remotes/origin/中的一个分支中,我发现了这个:761db53af177ecfd9c9b14511360537e041ebed7
C)当我们进行提交时,更改保存在哪里?
它们存储在 .git/objects 中吗?
最佳答案
这些在其他地方得到了零碎的回答,但我会继续在这里提供一个简短的综合答案:
refspec - as far as I understood maps the server branches to the "local" destination branches
这是一种效果,而不是定义。
refspec 的定义只是一对引用名称,用冒号分隔
:
,并带有可选的前导加号 +
.冒号左边的引用名称是来源,右边的名称是目的地。如果存在前导加号,则 refspec 表示 Git 应该执行“强制更新”,即更新引用,即使它不是快进(分支引用)或自然不允许(对于标签)。Refspecs 用于
git fetch
和 git push
.省略其中一个部分在不同的命令中会产生不同的效果,因此最容易使用双方都完整的 refspecs。与 git fetch
一起使用时,源确实是服务器的引用(通常是分支名称,但您可以复制标签、注释或服务器公开的任何其他引用——默认情况下,服务器公开所有内容)。正如您所猜测的,目的地是您自己的本地引用,通常也是一个分支名称。你的第一个问题:
A) Are they stored at .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
值(value):$ 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
任何给定 Remote 的配置。(对于名为
$rem
的远程,使用 git config --get-all remote.$rem.fetch
查看其默认获取引用规范。)如上所示,fetch refspecs 可能包含通配符
*
人物。这些很像 shell(sh、bash、zsh 等)“glob”字符,除了在旧版本的 Git2 中它们被限制在斜杠后立即出现 /
(例如,refs/heads/pr*
将被禁止),当然,当它们出现在目标端时,它们只会扩展回它们在源端匹配的任何内容,因此它们必须配对。B) If yes is the content of each .git/refs/remotes/origin/(branch) a reference/ID to the place where the changes are in the server?
排序:它是一个对象标识符。 (这个问题的确切形式暗示了一个错误的假设,我们稍后会谈到。)
因为
refs/remotes/origin/$branch
是远程跟踪分支名称(因此是 refs/heads/
命名空间分支名称的副本),它实际上必须指向 3 提交对象。注意名字的位置,在refs/
, 确定引用的类型。引用类型暗示了对象类型:大多数名称通常应该指向提交对象,但标记名称可以指向四种基本对象类型中的任何一种。 (四种类型是提交、树、blob 和标签或“带注释的标签”;标签名称通常应直接指向提交或带注释的标签对象。提交指向父提交和一棵树;树指向 blob 和额外的树;和 blob 包含文件内容。另见问题 C 的答案。)C) When we do a commit where are the changes save?
这就是你偏离轨道、陷入杂草的地方:Git 保存快照,而不是更改。但你大多是在正确的区域!
一张图胜过千言万语,所以我将包括a link to the Pro Git book chapter .
are they stored in the .git/objects ?
这是 Git 存储其“目标文件”的地方,是的。一个新的提交意味着一个新的对象,这个新的对象进入那个目录(实际的文件名被复杂化了 4 以使 Git 在 Linux 机器上运行得更快,其中“胖”目录很慢)。如上所述,新提交指向一棵树——通常是一个新的树对象,而不是一些现有的树对象——并且该树提供了从正常用户文件名(和文件模式,特别是执行位)到 Git blob 的映射。对象名称。树和 blob 对象也存储在
.git/objects
中。 .然而,更复杂的是,对象可能被打包到一个“打包文件”中。 (此时,Git 确实开始进行增量压缩,就像其他版本控制系统一样,但有一个显着的变化,即增量压缩不需要应用于“相同”文件的先前版本,甚至文件的在实践中,选择 delta 链的启发式目前与文件名和大小相关联,但原则上,我们可以针对树压缩文件,反之亦然,如果效果很好。)
1 简称为“写作时间”,而不是“答案长度”。 :-) 如果我花更长的时间,我可以写一个更短的答案......
2Git 2.5 左右的某个地方,但我没有时间查找放宽通配符放置限制的确切版本。
3这里的短语“指向”是“包含ID”的缩写,暗示我们——或Git——可以跟随这个ID来找到对象本身,就像跟随一个指向箭头:这条路到导出对象。
4 向非英语母语人士致歉:这不是一个真正的词,而是“complex”和“complication”的混合词,并添加了副词后缀“-ify”两次,用胶水、锉刀和砂纸打磨以适应,只是为了使并发症复杂化。 :-)
关于git - git Fetch 数据存储在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38164505/