是否可以在目录名称空间以外的地方的refspec中使用过滤器? [英] Is it possible to use filters in refspec in places other than directory namespaces?

查看:58
本文介绍了是否可以在目录名称空间以外的地方的refspec中使用过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看,这些示例显示refspec可以过滤目录/namespaces,如:

+refs/heads/qa/*:refs/remotes/origin/qa/*

但是,我正在尝试优化提取操作,并且正在使用的存储库具有这样的分支: release-6.0.0 当尝试过滤这些时,我得到:

fatal: Invalid refspec '+refs/heads/release*:refs/remotes/upstream/release*' 有什么方法可以在获取中过滤这些内容,还是我需要获取所有远程磁头?

解决方案

Git 2.6+(2015年第三季度)将允许这种refspec!

请参见提交cd377f4 Junio C Hamano-gitster-*" refspecs的限制

通过允许在组件中而不是仅在整个组件中具有"*"的模式来放松对refspec的限制.

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月)和提交b2a5627 ( Daniel Barkalow )强制执行通配符refspec必须以斜杠和星号结尾"的规则:

通配符refspec被内部解析为带有srcdst字符串的refspec结构.
代码的许多部分都假定在将通配符模式与我们在远程上看到的实际ref进行匹配时,这些部分不包含结尾的"/*".
这意味着我们不仅要确保前缀匹配,而且要确保匹配的部分后面有斜杠.

但是一个扫描ls-remote结果并找到匹配的引用的代码路径却忘记了检查匹配的部分必须后跟一个斜线"规则.
这导致远程的"refs/heads/b1"与"refs/heads/b/*:refs/remotes/b/*" refspec的源端错误地匹配.

更糟糕的是,由"git-clone"内部制作的refspec和用于实现"git-fetch --tags"的硬编码预编写refspec违反了此解析的widcard refspec不以斜杠结尾"规则;只需添加匹配部分必须后跟一个斜杠"规则,那么使用这些refspec的代码路径就会损坏.

此提交更改了规则,以要求在分析的通配符refspecs后面加上斜杠.
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 指出了 diff )作为此规则的起源(Git 1.5.5,2007年4月)

我们在较早的提交ef00d15 中收紧了refspec验证代码(收紧了refspec处理,2008-03-17),但我的建议一开始就被误导了,这破坏了这种用法:

$ git push origin HEAD~12:master

push refspecs和fetch refspecs的语法相似,因为它们都是冒号分隔的LHS和RHS(可能以+为前缀),但是相似之处到此结束. 例如,push refspec中的LHS可以是在运行时可评估为有效对象名称的任何内容(除非冒号和RHS缺失,或者它是一个glob),而它必须是 获取引用规范中具有有效外观的引用名.
为了正确验证它们,调用者必须能够说出它们是哪种refspec.
保持一个单一的接口无法分辨正在处理的类型,并要求其行为明智是不合理的.

此提交将两者的解析分离为不同的功能,并澄清了实现正确解析的代码(即拆分为两部分,确保双方都是通配符或双方都不是).

Looking at this the examples show refspecs can filter directories/namespaces as in:

+refs/heads/qa/*:refs/remotes/origin/qa/*

However I'm trying to optimise a fetch and the repo I'm working with has branches named like this: release-6.0.0 When trying to filter these I get:

fatal: Invalid refspec '+refs/heads/release*:refs/remotes/upstream/release*' Is there any way to filter these in the fetch or do I need to fetch all the remote heads?

解决方案

Git 2.6+ (Q3 2015) will allow this kind of refspec!

See commit cd377f4, commit 53a8555 (22 Jul 2015) by Jacob Keller (jacob-keller).
(Merged by Junio C Hamano -- gitster -- in commit 8d3981c, 03 Aug 2015)

refs: loosen restriction on wildcard "*" refspecs

Loosen restrictions on refspecs by allowing patterns that have a "*" within a component instead of only as the whole component.

Remove the logic to accept a single "*" as a whole component from check_refname_format(), and implement an extended form of that logic in check_refname_component().
Pass the pointer to the flags argument to the latter, as it has to clear REFNAME_REFSPEC_PATTERN bit when it sees "*".

Teach check_refname_component() function to allow an asterisk "*" only when REFNAME_REFSPEC_PATTERN is set in the flags, and drop the bit after seeing a "*", to ensure that one side of a refspec contains at most one asterisk.

This will allow us to accept refspecs such as for/bar*:foo/baz*.
Any refspec which functioned before shall continue functioning with the new logic.


Original answer (2013)

It doesn't seem possible, because that limitation facilitates refs matching done by remote.c.

That goes back to Git 1.5.6.5 (August 2008) and commit b2a5627 (Daniel Barkalow) which enforces the rule of "wildcard refspec must end with slash and star":

A wildcard refspec is internally parsed into a refspec structure with src and dst strings.
Many parts of the code assumed that these do not include the trailing "/*" when matching the wildcard pattern with an actual ref we see at the remote.
What this meant was that we needed to make sure not just that the prefix matched, and also that a slash followed the part that matched.

But a codepath that scans the result from ls-remote and finds matching refs forgot to check the "matching part must be followed by a slash" rule.
This resulted in "refs/heads/b1" from the remote side to mistakenly match the source side of "refs/heads/b/*:refs/remotes/b/*" refspec.

Worse, the refspec crafted internally by "git-clone", and a hardcoded preparsed refspec that is used to implement "git-fetch --tags", violated this "parsed widcard refspec does not end with slash" rule; simply adding the "matching part must be followed by a slash" rule then would have broken codepaths that use these refspecs.

This commit changes the rule to require a trailing slash to parsed wildcard refspecs.
IOW, "refs/heads/b/*:refs/remotes/b/*" is parsed as src = "refs/heads/b/" and dst = "refs/remotes/b/".
This allows us to simplify the matching logic because we only need to do a prefixcmp() to notice "refs/heads/b/one" matches and "refs/heads/b1" does not.


The OP Monte Goulding points out to commit 46220ca (diff) as being the origin of this rule (Git 1.5.5, April 2007)

We tightened the refspec validation code in an earlier commit ef00d15 (Tighten refspec processing, 2008-03-17) per my suggestion, but the suggestion was misguided to begin with and it broke this usage:

$ git push origin HEAD~12:master

The syntax of push refspecs and fetch refspecs are similar in that they are both colon separated LHS and RHS (possibly prefixed with a + to force), but the similarity ends there.
For example, LHS in a push refspec can be anything that evaluates to a valid object name at runtime (except when colon and RHS is missing, or it is a glob), while it must be a valid-looking refname in a fetch refspec.
To validate them correctly, the caller needs to be able to say which kind of refspecs they are.
It is unreasonable to keep a single interface that cannot tell which kind it is dealing with, and ask it to behave sensibly.

This commit separates the parsing of the two into different functions, and clarifies the code to implement the parsing proper (i.e. splitting into two parts, making sure both sides are wildcard or neither side is).

这篇关于是否可以在目录名称空间以外的地方的refspec中使用过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆