为什么“git clone”不接受refspec?

时间:2013-12-17 21:03:08

标签: git jenkins gerrit

似乎有很多人用组合git clone替换git init && git fetch。这看起来相当愚蠢,不幸的是像詹金斯这样的工具不会为你做那件事。那么为什么git clone不采用refspec,就像git fetch一样呢?

具体来说,如果您希望在Jenkins上运行gerrit触发的构建任务,则需要确保工作区存在,否则jenkins将无法签出包含gerrit更改的修订版。这是因为gerrit使用的ref路径不属于git clone提取的路径。

2 个答案:

答案 0 :(得分:5)

git clone 通过通用refspec option

获取--config

  

在新创建的存储库中设置配置变量;这在初始化存储库之后,但在获取远程历史记录或检出任何文件之前立即生效。 [...]这样可以安全地,例如,向源远程添加额外的fetch refspec。

示例:

 git clone -c remote.origin.fetch=+refs/changes/*:refs/remotes/origin/changes/* https://gerrit.googlesource.com/git-repo

然而,我刚刚意识到这对我git version 2.12.2.windows.2没有预期效果,因为在克隆时changes引用并不真正被提取。它被正确添加到.git/config,但我需要在克隆后通过

手动获取它
cd git-repo
git fetch

修改:结果为known bug

答案 1 :(得分:3)

请指定gerrit使用的refname是什么,克隆后缺少这个名称。只需git clone --origin <gerrit-suitable-origin-name>解决问题吗?

现在是长版本。你的问题可能是两个问题的组合。为什么git initgit remote addgit fetch有利,为什么在最初克隆存储库时没有方便地过滤refspec的方法?

refspecs - 在克隆初始化一个repo之后,该命令的remote-refspec行为是向.gitconfig添加一个默认部分,该部分概述了fetch规范:

[remote "origin"]
url = ssh://host/your.git
fetch = +refs/heads/*:refs/remotes/origin/*

这些是优秀且理智的默认值,并且提供的refspec旨在从远程获取所有内容。如果您需要更改refspecs,可以通过编辑文件手动完成。例如,

[remote "origin"]
url = ssh://host/your.git
fetch = +refs/heads/atari:refs/remotes/origin/atari
fetch = +refs/heads/vertigo:refs/remotes/origin/vertigo

在编辑之后,提取将仅涉及来自原始远程的atarivertigo分支,以及例如通常存在的master以及可能存在于其上的所有其他分支。遥控器被忽略。这当然类似于在命令行上向git fetch提供refspec的选项。

总的来说,没有必要,并且我认为不是一个干净的设计,能够在git clone命令行上预先支持多个初始refspec,其唯一目的是将它们放在.gitconfig中。您甚至可以通过在.gitconfig文件上运行git clone然后sed来编写相同的脚本。考虑到许多可能的refspec,在克隆时确定哪个是结帐的初始分支也是有问题的。

init over clone - 假设我们避免讨论更高级的git clone设置,例如利用--reference,浅深度--depth或创建裸回购,init-add-fetch和clone之间的区别对于你的日常流程来说是非常小的。

普通克隆只复制现有存储库并将“origin”设置为创建源的远程。这带来了一些小麻烦 - 强迫你使用“原点”遥控器,创建远程跟踪分支,设置初始分支,并检查HEAD。但是,如果您从git init开始,则您可以稍微控制一下。您可以手动添加遥控器并获取特定分支,而无需检查任何内容。

注意虽然git clone行为的许多方面都可以通过命令行开关来控制 - 所以喜欢git init的开发人员可能不知道它们?问题中没有足够的信息来决定。与替代方案相比,git clone可以为您节省一些打字,避免宇宙热死亡,并设置合理的上游默认值 - 例如掌握跟踪分支。我投票支持克隆。