git - git Fetch 数据存储在哪里?

标签 git

我是 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 fetchgit push .省略其中一个部分在不同的命令中会产生不同的效果,因此最容易使用双方都完整的 refspecs。与 git fetch 一起使用时,源确实是服务器的引用(通常是分支名称,但您可以复制标签、注释或服务器公开的任何其他引用——默认情况下,服务器公开所有内容)。正如您所猜测的,目的地是您自己的本地引用,通常也是一个分支名称。

你的第一个问题:

A) Are they stored at .git/refs/remotes/origin/(branches)?



默认情况下,是的。但请注意几个警告:
  • 找到.git目录,使用 git rev-parse --show-toplevelgit rev-parse --show-cdup如果您在子目录中。
  • 引用名称可能会被打包,在这种情况下,它们不会存储在它们自己的单独文件中。
  • Git 正在(内部)为 ref-names 发展一个可插入的后端,因此即使上述内容也可能发生变化:要从脚本解析或更新 ref-names,您应该使用 Git 的“管道”命令,即 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/

    相关文章:

    git - 是否可以在知道提交哈希但无法访问存储库的情况下获取提交的时间/日期?

    git - 有没有办法将文件的特定版本添加到 git 索引?

    git - 检查本地和远程分支差异的有效方法

    git - 无法将代码推送到 Github

    git - 加速 bash 脚本将 git repo 转换为 LFS

    git - 如何将GIT中的2个分支 merge 为一个具有2个文件夹的分支

    ruby - 如何在不在标准输出中显示的情况下捕获命令的输出

    git - 如何在 Git 中重命名带注释的标签

    windows - rhc 设置和 openshift 问题

    git - 添加你的 .vim ~/.vimrc 到 github(又名点文件)