如何测试Git仓库是否为浅层仓库?

35

当我从一个仓库进行本地克隆时,如果源仓库是浅层的,则克隆失败。

git clone -l -- . target-dir

由于并非总是这样,因此我想在克隆之前找出克隆源,但不知道该如何操作。

到目前为止,我尝试的很少,基本上只是在克隆时创建错误消息。目前我只是获取以取消浅克隆,如果失败,我会执行普通的获取操作,因为如果仓库是浅克隆,则之后应将其还原为深度克隆:

if ! git fetch --unshallow; then
    git fetch
fi

然而,之后仍无法保证不肤浅(远程获取的内容也可能很肤浅),因此最好测试git存储库的(不)肤浅性。


什么问题? - Whymarrh
@Whymarrh:“如何测试Git仓库是否为浅层仓库?”,我刚刚编辑了一下,之前使用的是内置搜索的标题。 - hakre
2个回答

54

If your Git is 2.15 or later, run:

git rev-parse --is-shallow-repository

将会打印 false(非浅拷贝)或者 true(浅拷贝):

if $(git rev-parse --is-shallow-repository); then
    ... repository is shallow ...
fi

以下答案适用于Git 2.15版本之前。


如果您使用的Git版本早于2.15,1只需在Git存储库目录中测试文件shallow:2

if [ -f "$(git rev-parse --git-dir)"/shallow ]; then
    echo this is a shallow repository;
else
    echo not a shallow repository;
fi

或(更短):

[ -f "$(git rev-parse --git-dir)"/shallow ] && echo true || echo false
您可以将此转换为 shell 函数:
test_shallow() {
    [ -f "$(git rev-parse --git-dir)"/shallow ] && echo true || echo false
}

甚至可以自动化Git版本检查:

test_shallow() {
    set -- $(git rev-parse --is-shallow-repository)
    if [ x$1 == x--is-shallow-repository ]; then
        [ -f "$(git rev-parse --git-dir)"/shallow ] && set true || set false
    fi
    echo $1
}

1git --version 将显示当前的版本号:

$ git --version
2.14.1

$ git --version
git version 2.7.4

等等。(我现在有不同版本的虚拟机/机器。)您还可以运行:

git rev-parse --is-shallow-repository

如果它只打印--is-shallow-repository,那么你的Git版本低于2.15,缺少该选项。

2要了解为什么在$(git rev-parse --git-dir)周围有双引号,请参见Tom Hale的评论。请注意,测试这个有点棘手,因为从如/tmp/with space的仓库的顶层运行git rev-parse --git-dir只会打印出.git; 您必须处于子目录中,例如/tmp/with space/sub才能观察到该问题。


只要存储库是浅的,git-dir 中就会有“shallow”文件,不是吗?测试一下,听起来很有前途,非常感谢你到目前为止的回答。 - hakre
从测试中发现:删除浅层文件会让 Git 认为它不是浅层克隆,从而允许本地克隆。此外,我注意到我的当前 Git 版本如果检测到浅层克隆,则忽略 --local 参数,仍然会回退到非本地克隆。此时退出状态码为 0。 - hakre
1
shallow文件不仅仅是一个标记,它还包含了使其成为浅层存储库的嫁接点(如果您删除该文件,则只是一个损坏的存储库)。通常不明智地将其删除:请留给成功取消浅化的fetch处理。 - torek
@torken:我只是为了测试而将其删除,因为我想尝试一下会发生什么。我进行检查,如果是浅层的,则通过fetch取消浅层。 - hakre
为了允许目录名中包含空格,请确保正确使用双引号:"$(git rev-parse --git-dir)" - Tom Hale
@TomHale:好的,有道理,我会更新示例片段。 - torek

1
当您无法访问远程存储库(虽然此处不是这种情况,但仍有可能),git clone 仍然是测试该远程存储库是否为浅存储库的好方法。
问题在于,如果由于所述远程存储库的浅性而最终克隆失败,则不必要地传输/创建文件。
Git 2.32(2021 年第二季度)现已修复此问题: "git clone"(man) 新的 --reject-shallow 选项会在我们注意到正在从浅存储库进行克隆时立即使克隆失败。

请看4fe788b提交(2021年4月1日)由Li Linchao (Cactusinhand)提交。
(由Junio C Hamano -- gitster --22eee7f提交中合并,2021年4月8日)

builtin/clone.c:添加--reject-shallow选项

签名:Li Linchao

在某些情况下,用户可能需要比克隆提供的浅存储库更多的历史记录。但是因为用户在下载到本地之前不知道它是一个浅存储库,所以我们可能希望拒绝克隆这种存储库,而不创建任何不必要的文件。
'--depth=x'选项不能用作解决方案;源可能足够深,以便在克隆时给我们'x'个提交,但用户稍后可能需要加深历史记录到任意深度。
教 "git clone"(man) 使用 '--reject-shallow' 选项,一旦发现从浅存储库进行克隆即中止。

没有创建本地文件!

错误消息将为(使用测试克隆命令):

git -c clone.rejectshallow=true clone --no-local shallow-repo
source repository is shallow, reject to clone.

git config现在在man page中包含:

clone.rejectShallow

如果是浅层仓库,则拒绝克隆存储库,可以通过在命令行中传递选项--reject-shallow来覆盖。

git clone现在在man page中包含:

--[no-]reject-shallow

如果源存储库是浅层存储库,则失败。
'clone.rejectShallow'配置变量可用于指定默认值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接