【问题标题】:Make a shallow GIT repository less shallow让浅 GIT 存储库不那么浅
【发布时间】:2014-06-18 20:20:07
【问题描述】:

我为指定的标签创建一个浅克隆:

git clone --branch v0.1.3 --depth 1 file:///c/usr/sites/smc .

在此之后,克隆的 repo 中仅包含标签 v0.1.3(和相关文件)。 它没有该标签之前或之后的所有更改的历史记录(据我所知 - 如果有错误,请纠正我。) 接下来我想更新克隆以包含 v0.1.4。 如果我使用“git fetch --unshallow”命令,那么我会得到我不想要的完整历史记录。 有没有办法扩展我的克隆以包含来自主人的新历史(如 v0.1.4 和 0.1.5),但不包括旧历史(如 0.1.2)? (我看到一个名为 update-shallow 的选项,但不明白它的作用或是否相关。)

这样做的目标是:

1) 通过不克隆整个存储库,使远程服务器上存储库的初始设置快速而小型化。 (我们的 repo 主要是二进制文件:DLL、EXE。)

2) 可以将远程 repo 升级到更高版本(由标签给出),但不能升级到更早版本。这样的升级只会转移存储库的一小部分,所以它也应该很快。

注意:我的 Git 版本是 Windows 7 上的 1.9.2.msysgit.0。这包括最近对浅克隆的增强。 我们可能会在 Linux 上托管主存储库,但我们部署的代理运行 Windows。 目的是使用 puppet 企业管理结帐。

更新: 尝试了 VonC 的建议。

$ git fetch --update-shallow origin v0.1.4
remote: Counting objects: 6, done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From file:///c/usr/sites/smc
 * tag               v0.1.4     -> FETCH_HEAD

paul.chernoch@USB-XXXXXXXXX /c/usr/sites/smc-clone3 ((v0.1.3))
$ git describe
v0.1.3

paul.chernoch@USB-XXXXXXXXX /c/usr/sites/smc-clone3 ((v0.1.3))
$ git tag --list
v0.1.3

虽然该命令似乎在执行某些操作,但我在目标存储库中看不到标签 v0.1.4。但是,如果我使用 --tags 选项,我会得到所有的标签,还有所有的历史! 另外,我不理解 git fetch 命令输出中的符号“FETCH_HEAD”。

更新: 进一步的研究表明,这个 SO 问题是为了一个类似的目标: git shallow clone to specific tag

【问题讨论】:

  • update-shallow 在github.com/git/git/commit/…github.com/git/git/commit/… 中被提及。你试过git fetch --update-shallow origin v0.1.4吗?
  • @VonC:感谢您提供的链接。我的源代码库并不浅,而我的目标很浅,因此根据您的信息,看起来 --update-shallow 不是我想要的,但无论如何我都会尝试。

标签: git clone shallow-clone


【解决方案1】:

似乎我对此有类似的问题,后来发现了这个。诀窍是在 fetch 命令的末尾和深度指定完整的 refspec。 refs/tags/v0.1.3:refs/tags/v0.1.3 或简称为tag v0.1.3

Git shallow fetch of a new tag

git fetch --depth 1 origin tag v0.1.4

【讨论】:

    【解决方案2】:

    此选项更新.git/shallow 并接受此类引用。

    但这将与 Git 2.27(2020 年第二季度)一起更好地工作,它修复了在提取到一个浅层存储库后的内核不一致问题,该存储库破坏了代码以写出 commit-graph

    这也会影响git push

    参见commit 37b9dca(2020 年 4 月 23 日)和 commit 8a8da49(2020 年 4 月 24 日)Taylor Blau (ttaylorr)
    (由 Junio C Hamano -- gitster -- 合并到 commit 2b4ff3d,2020 年 5 月 1 日)支持>

    shallow.c:使用'{commit,rollback}_shallow_file'

    帮助:Jonathan Tan
    帮助:Junio C Hamano
    签字:Taylor Blau
    审核人:Jonathan Tan

    bd0b42aed3(“fetch-pack:不要不必要地采取浅锁”,2019-01-10,Git v2.21.0-rc0 -- merge列在batch #4)中,作者指出' is_repository_shallow' 通过设置 'is_shallow' 和 'shallow_stat' 产生可见的副作用。

    这是一个问题,例如,在启用了“fetch.writeCommitGraph”的浅层存储库中使用“--update-shallow”获取,因为更新到“.git/shallow”会导致 Git 认为存储库不是浅层的当它是时,从而绕过提交图兼容性检查。

    这会导致浅层存储库中出现问题,这些浅层存储库至少具有至少一个祖先的浅层引用(因为客户端不会拥有这些对象,因此在编写 commit-graph 时无法对提交进行可达性关闭)。

    通过在 'commit_lock_file' 和 'rollback_lock_file' 上引入薄包装器来解决这个问题,以便专门在锁定在 '.git/shallow' 上时使用。
    这些包装器(适当地称为“commit_shallow_file”和“rollback_shallow_file”)在“lockfile.h”中调用它们各自的函数,但还会重置浅层机制使用的有效性检查。

    当持有的锁在“.git/shallow”文件上方时,将“commit_lock_file”和“rollback_lock_file”的每个实例替换为“commit_shallow_file”和“rollback_shallow_file”。

    因此,“prune_shallow”现在只能被调用一次(因为“check_shallow_file_for_update”在调用“reset_repository_shallow”后会死掉)。但是,这没关系,因为我们每个进程最多只调用一次“prune_shallow”。


    警告,在 Git 2.28(2020 年第三季度)之前,“fetch.writeCommitGraph”在请求“feature.experimental”时已启用,但发现即使对于当前形状的大胆人来说,它也有点太冒险了。

    至少目前,该配置已从“实验性”功能集中退出。

    参见Jonathan Nieder (artagnon)commit b5651a2(2020 年 7 月 6 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit 9850823,2020 年 7 月 9 日)

    experimental:默认为 fetch.writeCommitGraph=false

    报告人:Jay Conrod
    帮助人:Taylor Blau
    签字人:Jonathan Nieder

    fetch.writeCommitGraph 功能使 fetches 在 fetch 上为新下载的包写出提交图文件。

    这提高了执行修订遍历的各种命令的性能,最终应该成为每个人的默认设置。

    为了为未来做好准备,默认情况下会为设置 feature.experimental=true 的用户启用该功能以体验未来的默认设置。

    唉,--unshallow 从浅克隆中获取它遇到了一个障碍:当 Git 获取新对象并正在编写提交图时,它已经执行了修订遍历,r->parsed_objects 包含有关在获取之前的浅边界。

    提交图编写代码小心避免将提交图文件写入浅层存储库,但新状态并不浅,结果是从那时起,“git log”之类的命令会使用新的用旧的浅边界表示虚构历史的书面提交图文件。

    我们可以通过让提交图编写代码更加小心来解决此问题,以避免编写可能使用任何移植或浅状态的提交图,但可能还有其他变异状态片段会获取提交图编写代码可能会依赖。

    所以在 feature.experimental 配置中禁用它。

    自 4 月发现此错误以来,Google 开发人员一直在此配置中运行(通过在系统配置中设置 fetch.writeCommitGraph=false)来解决此错误。

    一旦修复成功,我们将再次启用fetch.writeCommitGraph=true,以便在向更广泛的受众推出之前对其进行一些早期测试。

    换句话说:

    • 这个补丁只影响feature.experimental=true的行为
    • 它使 feature.experimental 与 Google 过去几个月一直在使用的配置相匹配,这意味着与没有它相比,它会让用户处于更好的测试状态
    • 这应该会改进对 feature.experimental 保护的其他功能的测试,让 feature.experimental 更安全地使用

    另外,仍然使用 Git 2.28(2020 年第三季度),当在浅存储库中设置“fetch.writeCommitGraph”配置并且 fetch 移动浅边界时,我们写出了与现实不符的损坏的提交图文件,已更正。

    参见Taylor Blau (ttaylorr)commit ce16364(2020 年 7 月 8 日)。
    (由 Junio C Hamano -- gitster -- 合并于 commit 24ecfdf,2020 年 7 月 9 日)

    commit.c: 不肤浅时不要坚持替代父母

    帮助者:Derrick Stolee
    帮助者:Jonathan Nieder
    报告者:Jay Conrod
    审核人:Jonathan Nieder
    签字人:Taylor Blau

    由于37b9dcabfc (shallow.c: use '{commit,rollback}_shallow_file', 2020-04-22),Git 知道如何重置$GIT_DIR/shallow 文件的统计有效性检查,允许它在浅层和同一进程中的非浅层状态(例如,在 'git fetch --unshallow' 的情况下)。

    但是,当$GIT_DIR/shallow 更改时,Git 不会更改或删除内存中的任何移植物(也不会替代父代)。

    这出现在 fetch.writeCommitGraph 设置为 true 的“git fetch --unshallow”中。通常在浅层存储库中(在 37b9dcabfc 之前,即使在这种情况下),commit_graph_compatible() 将返回 false,表明该存储库不应该用于编写提交图(因为提交图文件不能代表浅层历史)。但是由于37b9dcabfc,在一个--unshallow 操作中检查成功。

    因此,即使存储库不再是浅层(也就是说,我们拥有所有对象),这些对象的核心表示仍然在浅层边界处具有 munged 父级。

    当提交图写入继续时,我们使用了不正确的父系,产生了错误的结果。

    用户有两种解决方法:(1) 将“fetch.writeCommitGraph”设置为“false”,或 (2) 在 unshallowing 后删除提交图。

    解决此问题的一种方法是在 unshallowing 之后完全重置已解析的对象池(刷新缓存,从而防止后续读取修改其父对象)。当调用者对旧池的引用现在已经过时时,这会产生问题,因此这个补丁实现了不同的方法。相反,将一个新位附加到池中,'substituted_parent',它指示存储库是否曾经存储了一个修改了其父级的提交(即,在 unshallowing 之前的浅边界)。 p>

    这个位需要粘性,因为在修改提交的父级之后的所有读取在不浅化时都是不可靠的。修改 'commit_graph_compatible' 中的 check 以考虑该位,并正确避免在这种情况下生成提交图,从而解决 bug。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2019-03-02
      • 1970-01-01
      • 2020-07-04
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多