使浅GIT存储库不那么浅薄

时间:2014-06-18 20:20:07

标签: git clone shallow-clone

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

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)通过不克隆整个仓库,使远程服务器上的存储库的初始设置变得快而小。 (我们的回购主要是二进制文件:DLL,EXE。)

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

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

更新: 尝试过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”。

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

2 个答案:

答案 0 :(得分:2)

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

Git shallow fetch of a new tag

git fetch --depth 1 origin tag v0.1.4

答案 1 :(得分:0)

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

但是,这与Git 2.27(2020年第二季度)一起使用会更好,后者在获取浅层存储库后打破了代码写出commit-graph的问题,从而解决了内核内的不一致问题。

这也会影响git push

请参见commit 37b9dca前的commit 8a8da49(2020年4月23日)和Taylor Blau (ttaylorr)(2020年4月24日)。
(由Junio C Hamano -- gitster --commit 2b4ff3d中合并,2020年5月1日)

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

帮助者:Jonathan Tan
帮助者:Junio C Hamano
签名人:泰勒·布劳
作者:Jonathan Tan

bd0b42aed3中(“ fetch-pack:不要不必要地进行浅锁”,2019年1月10日,{{3}中列出的Git v2.21.0-rc0-merge }),作者注意到“ is_repository_shallow”通过设置“ is_shallow”和“ shallow_stat”产生明显的副作用。

这是一个问题,例如,在启用了“ --update-shallow”的浅存储库中以“ fetch.writeCommitGraph”进行获取,因为更新为“ .git/shallow”会导致Git认为存储库不是很浅,从而规避了提交图兼容性检查。

这会在浅存储库中导致问题,这些浅存储库中至少具有至少一个祖先的浅引用(因为客户端将没有这些对象,因此在编写commit-graph时不能超过提交的可达性闭包) )。

通过在“ commit_lock_file”和“ rollback_lock_file”上引入薄包装器来解决此问题,以专门用于将锁定保持在“ .git/shallow”上时使用。 这些包装器(分别称为“ commit_shallow_file”和“ rollback_shallow_file”)在“ batch #4”中调用它们各自的功能,但另外还重置了浅层机制使用的有效性检查。

当持有的锁位于'{{1}上方时,将'commit_lock_file和'rollback_lock_file'的每个实例替换为'commit_shallow_file和'rollback_shallow_file' }}”文件。

因此,“ .git/shallow”现在只能被调用一次(因为“ prune_shallow”将在调用“ check_shallow_file_for_update”之后消失)。但是,这是可以的,因为每个进程最多只能调用一次“ reset_repository_shallow”。


警告,在Git 2.28(2020年第3季度)之前,当要求“功能。实验”时启用了“ prune_shallow”,但即使对于当前状态的大胆人来说,这样做也有些冒险

至少到目前为止,该配置已从“实验”功能集中弹出。

请参见lockfile.hcommit b5651a2(2020年7月6日)。
(由Jonathan Nieder (artagnon)Junio C Hamano -- gitster --中合并,2020年7月9日)

commit 9850823:默认为fetch.writeCommitGraph = false

举报人:Jay Conrod
帮助人:泰勒·布劳
签名人:乔纳森·尼德

fetch.writeCommitGraph功能使获取操作在获取时为新下载的包写出提交图文件。

这提高了执行修订修订的各种命令的性能,最终应该成为所有人的默认命令。

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

A,对于fetch.writeCommitGraph从浅克隆中获取,它遇到了一个障碍:当Git提取新对象并编写提交图时,它执行了修订遍历,并且--unshallow包含有关提取前 的浅边界的信息。

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

我们可以通过使提交图编写代码更加谨慎来避免编写可能使用任何嫁接或浅层状态的提交图来解决此问题,但是有可能存在其他一些突变状态来获取提交图编写代码可能是依靠。

因此请在feature.experimental配置中将其禁用。

自4月份发现该错误以来,Google开发人员一直在使用此配置(通过在系统配置中设置r->parsed_objects)来解决该错误。

修复程序登陆后,我们将再次启用fetch.writeCommitGraph=false,以便对其进行一些早期测试,然后再推广到更广泛的受众。

换句话说:

  • 此修补程序仅影响fetch.writeCommitGraph=true的行为
  • 它使feature.experimental与Google过去几个月一直使用的配置相匹配,这意味着与没有配置相比,它将使用户处于更好的测试状态
  • 这应该通过使feature.experimental更安全地使用
  • 来改善对feature.experimental=true保护的其他功能的测试。

此外,仍然使用Git 2.28(2020年第3季度),当在浅存储库中设置了“ feature.experimental”配置并且提取操作移动浅边界时,我们写出了与Git不匹配的损坏的提交图文件现实,已经得到纠正。

请参见experimentalcommit ce16364(2020年7月8日)。
(由Taylor Blau (ttaylorr)Junio C Hamano -- gitster --中合并,2020年7月9日)

commit 24ecfdf:取消隐藏时不要坚持替代父母

帮助:Derrick Stolee
帮助人:乔纳森·尼德
报告人:杰伊·康罗德
评论人:乔纳森·尼德
签名人:泰勒·布劳

由于commit.c37b9dcabfc:使用'fetch.writeCommitGraph',2020-04-22),Git知道如何为{commit,rollback}_shallow_file文件重置统计信息有效性检查,允许它在同一过程中在浅状态和非浅状态之间切换(例如,在'git fetch --unshallow'的情况下)。

但是,$GIT_DIR/shallow发生变化时,Git不会更改或删除内存中的任何嫁接(也没有替代的亲本)。

这出现在fetch.writeCommitGraph设置为true的“ git fetch --unshallow”中。通常,在浅存储库中(即使在这种情况下,在shallow.c之前),$GIT_DIR/shallow也会返回false,指示不应使用该存储库写入提交图(因为提交图文件不能代表浅薄的历史)。但是从37b9dcabfc开始,在--unshallow操作中,检查成功。

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

在提交提交图时,我们使用了不正确的父母身份,从而产生了错误的结果。

有两种方法可以解决此问题:(1)将'fetch.writeCommitGraph'设置为'false',或(2)取消提交后删除提交图。

解决此问题的一种方法是在取消整理后完全重置已解析的对象池(刷新缓存,从而防止后续读取修改其父对象)。当调用者对旧池有一个过时的引用时,就会产生问题,因此此修补程序实现了另一种方法。取而代之的是,在池中添加新的位{commit_graph_compatible()',它指示存储库 ever 是否存储了已修改其父项的提交(即,在取消精简之前的浅边界)。

该位需要保持粘性,因为在取消提交时,修改提交的父级之后的所有读取都不可靠。修改“ substituted_parent”中的检查以考虑到这一点,并在这种情况下正确避免生成提交图,从而解决了该错误。