Git 2.6+(2015 年第三季度)将允许这种 refspec!
参见commit cd377f4、commit 53a8555(2015 年 7 月 22 日)Jacob Keller (jacob-keller)。
(由 Junio C Hamano -- gitster -- 合并于 commit 8d3981c,2015 年 8 月 3 日)
refs:放宽对通配符“*”参考规范的限制
通过允许在组件中包含“*”而不是仅作为整个组件的模式来放宽对 refspecs 的限制。
从check_refname_format() 中删除接受单个“*”作为整个组件的逻辑,并在 check_refname_component() 中实现该逻辑的扩展形式。
将指向 flags 参数的指针传递给后者,因为它必须在看到“*”时清除 REFNAME_REFSPEC_PATTERN 位。
教导check_refname_component() 函数仅在标志中设置REFNAME_REFSPEC_PATTERN 时允许星号“*”,并在看到“*”后丢弃该位,以确保 refspec 的一侧最多包含一个星号。
这将使我们能够接受参考规范,例如for/bar*:foo/baz*。
之前运行的任何 refspec 都应继续使用新逻辑运行。
原始答案(2013 年)
这似乎不可能,因为这种限制有助于remote.c 完成的引用匹配。
这可以追溯到 Git 1.5.6.5(2008 年 8 月)和 commit b2a5627 (Daniel Barkalow),它们强制执行“通配符 refspec 必须以斜杠和星号结尾”的规则:
通配符 refspec 在内部被解析为带有 src 和 dst 字符串的 refspec 结构。
当将通配符模式与我们在远程看到的实际引用匹配时,代码的许多部分假定这些不包括尾随的“/*”。
这意味着我们不仅需要确保前缀匹配,而且还要确保匹配的部分后面有一个斜线。
但是从ls-remote 扫描结果并找到匹配引用的代码路径忘记检查“匹配部分必须后跟斜杠”规则。
这导致来自远程端的“refs/heads/b1”错误地匹配“refs/heads/b/*:refs/remotes/b/*”refspec 的源端。
更糟糕的是,由“git-clone”内部制作的 refspec 以及用于实现“git-fetch --tags”的硬编码预解析 refspec 违反了“解析的widcard refspec 不以斜线结尾”规则;只需添加“匹配部分必须后跟斜杠”规则,就会破坏使用这些 refspecs 的代码路径。
此提交将规则更改为需要尾部斜杠来解析通配符 refspec。
IOW,“refs/heads/b/*:refs/remotes/b/*”被解析为src = "refs/heads/b/" 和dst = "refs/remotes/b/"。
这让我们可以简化匹配逻辑,因为我们只需要做一个prefixcmp() 即可
注意“refs/heads/b/one”匹配而“refs/heads/b1”不匹配。
OP Monte Goulding 指出 commit 46220ca (diff) 是此规则的起源(Git 1.5.5,2007 年 4 月)
根据我的建议,我们在较早的 commit ef00d15(Tighten refspec 处理,2008-03-17)中收紧了 refspec 验证代码,但该建议一开始就被误导了,它破坏了这种用法:
$ git push origin HEAD~12:master
push refspecs 和 fetch refspecs 的语法相似,它们都是用冒号分隔的 LHS 和 RHS(可能以 + 为前缀强制),但相似之处到此为止。
例如,push refspec 中的 LHS 可以是在运行时计算为有效对象名称的任何内容(除非冒号和 RHS 丢失,或者它是一个 glob),而它必须是
fetch refspec 中看起来有效的 refname。
为了正确验证它们,调用者需要能够说出它们是哪种类型的 refspec。
保留一个无法判断它在处理哪种类型的接口,并要求它表现得明智是不合理的。
此提交将两者的解析分离为不同的函数,并澄清代码以实现正确的解析(即分成两部分,确保两边都是通配符或两边都不是)。