Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何检查有效的Git分支名称?_Python_Regex_Git_Githooks - Fatal编程技术网

Python 如何检查有效的Git分支名称?

Python 如何检查有效的Git分支名称?,python,regex,git,githooks,Python,Regex,Git,Githooks,我正在开发一个新的。数据在stdin上提供,行与 ef4d4037f8568e386629457d4d960915a85da2ae 61a4033ccf9159ae69f951f709d9c987d3c9f580 refs/heads/master 第一个散列是旧的ref,第二个散列是新的ref,第三列是正在更新的引用 我想把它分成3个变量,同时验证输入如何验证分支名称? 我目前正在使用以下正则表达式 ^([0-9a-f]{40}) ([0-9a-f]{40}) refs/heads/([0-

我正在开发一个新的。数据在
stdin
上提供,行与

ef4d4037f8568e386629457d4d960915a85da2ae 61a4033ccf9159ae69f951f709d9c987d3c9f580 refs/heads/master
第一个散列是旧的ref,第二个散列是新的ref,第三列是正在更新的引用

我想把它分成3个变量,同时验证输入如何验证分支名称?

我目前正在使用以下正则表达式

^([0-9a-f]{40}) ([0-9a-f]{40}) refs/heads/([0-9a-zA-Z]+)$
这不接受中列出的所有可能的分支名称。例如,它排除了名为
buildmaster
的分支,这是有效的

奖金分数 我实际上想排除任何以“build-”开头的分支。这可以在同一个正则表达式中完成吗

测验 根据下面的答案,我写了一些测试,可以在


状态:下面的所有正则表达式都无法编译。这可能表明我的脚本或不兼容的语法有问题。

让我们剖析各种规则并从中构建正则表达式部分:

  • 它们可以包括用于分层(目录)分组的斜杠
    /
    ,但斜杠分隔的组件不能以点
    开头或以序列
    .lock
    结尾

     # must not contain /.
     (?!.*/\.)
     # must not end with .lock
     (?<!\.lock)$
    
  • 它们不能有两个连续的点。。

     (?!.*\.\.)
    
     [^\000-\037\177 ~^:]+   # pattern for allowed characters
    
  • 它们不能有ASCII控制字符(即值小于
    \040
    \177 DEL
    的字节)、空格、波浪号
    ~
    、插入符号
    ^
    或冒号

     (?!.*\.\.)
    
     [^\000-\037\177 ~^:]+   # pattern for allowed characters
    
  • 它们不能有问号
    、星号
    *
    或开括号
    [
    。有关此规则的例外情况,请参阅下面的
    --refspec pattern
    选项

     [^\000-\037\177 ~^:?*[]+   # new pattern for allowed characters
    
  • 它们不能以斜杠开始或结束
    /
    ,也不能包含多个连续的斜杠(有关此规则的例外情况,请参阅下面的
    --normalize
    选项)

  • 它们不能包含序列
    @{

     (?!.*@\{)
    
  • 它们不能包含
    \

     (?!.*\\)
    
  • 将所有这些拼凑在一起,我们得到了以下怪物:

    ^(?!.*/\.)(?!.*\.\.)(?!/)(?!.*//)(?!.*@\{)(?!.*\\)[^\000-\037\177 ~^:?*[]+/[^\000-\037\177 ~^:?*[]+(?<!\.lock)(?<!/)(?<!\.)$
    
    这也可以通过合并一些寻找通用模式的东西来进行优化:

    ^(?!@$|build-|/|.*([/.]\.|//|@\{|\\))[^\000-\037\177 ~^:?*[]+/[^\000-\037\177 ~^:?*[]+(?<!\.lock|[/.])$
    

    ^(?!$| build-|/|*([/.]\.[/.]\/.[^\000-\037\177~^:?*[]+/[^\000-\037\177~:?*[]+(?直接从链接页获取规则,以下正则表达式应仅匹配
    引用/heads
    中的有效分支名称,而不是以“build-”开头:


    这将对分支名称的每一部分应用基本相同的规则,但只检查最后一个分支名称是否以
    build-

    开头。对于遇到此问题并希望PCRE正则表达式与有效的Git分支名称匹配的人,如下所示:

    ^(?!/|.*([/.]\.|//|@\{|\\\\))[^\040\177 ~^:?*\[]+(?<!\.lock|[/.])$
    
    ^(?!/.*([/.]\.[/.\/.\\\\\)[^\040\177~ ^:?*\[]+(?)?
    这是作者编写的正则表达式的修订版本。但是,在此版本中,不需要斜线(用于匹配
    branchName
    ,而不是
    refs/heads/branchName

    请参考他的正确答案。
    他提供了正则表达式每个部分的完整分解,以及它与上指定的每个需求的关系。

    没有必要用Perl编写monstrosities。只需使用/x:

    # RegExp rules based on git-check-ref-format
    my $valid_ref_name = qr%
       ^
       (?!
          # begins with
          /|                # (from #6)   cannot begin with /
          # contains
          .*(?:
             [/.]\.|        # (from #1,3) cannot contain /. or ..
             //|            # (from #6)   cannot contain multiple consecutive slashes
             @\{|           # (from #8)   cannot contain a sequence @{
             \\             # (from #9)   cannot contain a \
          )
       )
                            # (from #2)   (waiving this rule; too strict)
       [^\040\177 ~^:?*[]+  # (from #4-5) valid character rules
    
       # ends with
       (?<!\.lock)          # (from #1)   cannot end with .lock
       (?<![/.])            # (from #6-7) cannot end with / or .
       $
    %x;
    
    foreach my $branch (qw(
       master
       .master
       build/master
       ref/HEAD/blah
       /HEAD/blah
       HEAD/blah/
       master.lock
       head/@{block}
       master.
       build//master
       build\master
       build\\master
    ),
       'master blaster',
    ) {
       print "$branch --> ".($branch =~ $valid_ref_name)."\n";
    }
    
    #基于git check ref格式的RegExp规则
    我的$valid\u ref\u name=qr%
    ^
    (?!
    #开始于
    /|#(from#6)不能以开头/
    #包含
    .*(?:
    [/.]\.|#(from#1,3)不能包含/。或。。
    //|#(从#6开始)不能包含多个连续的斜杠
    @\{|#(来自#8)不能包含序列@{
    \\#(from#9)不能包含\
    )
    )
    #(从#2开始)(放弃此规则;过于严格)
    [^\040\177~^:?*[]+#(来自#4-5)有效字符规则
    #以
    (?
    
    Joey++对一些代码进行了修改。

    git check ref format
    带有
    子流程。Popen
    是一种可能性:

    import subprocess
    process = subprocess.Popen(["git", "check-ref-format", ref])
    exit_status = process.wait()
    
    优点:

    • 如果算法发生变化,检查将自动更新
    • 你一定会做对的,这对于一个怪物正则表达式来说要困难得多
    缺点:

    • 因为子流程而变慢。但过早优化是万恶之源
    • 需要Git作为二进制依赖项。但在钩子的情况下,它将始终存在

    ,它使用C绑定到,如果
    check ref format
    在那里公开,则可能性更大,因为它将比
    Popen
    快,但我还没有找到它。

    如果您想检查引用是否有效,可以像该函数()那样做:


    我猜猫比它们看起来更聪明。它们没有愚弄我!我很确定
    @{
    的负面外观必须与每个字符匹配,因为外观只检查紧接着的下一个字符,而不是字符串的其余部分(根据)。这就是为什么对Hanks@Joey来说,
    构建的前瞻功能正如您所期望的那样工作。请参见上面的编辑。我正在尝试测试正则表达式,但它们没有编译atm。@dregad:两者都已修复。我只需在Java中实现上面的正则表达式,也许它对其他人也会有用:
    “^(?。**/\”(?!。\\\\。(?!!/)(?!*/)(?!*/)(?!*/)(?!!*/)(?!!!*/)(?!!*)(?!)(?!!)(?!!)(?)(?!.\\\\)[^\000-\037\177~^:?*\[]+/[^\000-\037\177~^:?*\[]+(?谢谢@murgatroid99。请参见上面的编辑。我正在尝试测试正则表达式,但它们不是在编译atm。是否在包含正则表达式的字符串前面加上
    r
    (如
    r“regex”
    )前缀?对于包含转义序列的正则表达式,您必须这样做(使用“`”)否则它们将不正确。谢谢…略有改进…@Joey的前2个正在编译,但不是你的,也不是他的第3个。你的报告是不平衡的括号。我将开始调查。我很确定我已经修复了
    (?!.)((?!\.\.)(?!@{)[^\cA-\cZ ~^:?*[\\])+))(/(?!.)((?!\.\.)(?!@{)[^\cA-\cZ ~^:?*[\\])+)))*?/(?!.)(?!build-)((?!\.\.)(?!@{)[^\cA-\cZ ~^:?*[\\])+))(?<!\.)(?<!\.lock)
    
    ^(?!/|.*([/.]\.|//|@\{|\\\\))[^\040\177 ~^:?*\[]+(?<!\.lock|[/.])$
    
    # RegExp rules based on git-check-ref-format
    my $valid_ref_name = qr%
       ^
       (?!
          # begins with
          /|                # (from #6)   cannot begin with /
          # contains
          .*(?:
             [/.]\.|        # (from #1,3) cannot contain /. or ..
             //|            # (from #6)   cannot contain multiple consecutive slashes
             @\{|           # (from #8)   cannot contain a sequence @{
             \\             # (from #9)   cannot contain a \
          )
       )
                            # (from #2)   (waiving this rule; too strict)
       [^\040\177 ~^:?*[]+  # (from #4-5) valid character rules
    
       # ends with
       (?<!\.lock)          # (from #1)   cannot end with .lock
       (?<![/.])            # (from #6-7) cannot end with / or .
       $
    %x;
    
    foreach my $branch (qw(
       master
       .master
       build/master
       ref/HEAD/blah
       /HEAD/blah
       HEAD/blah/
       master.lock
       head/@{block}
       master.
       build//master
       build\master
       build\\master
    ),
       'master blaster',
    ) {
       print "$branch --> ".($branch =~ $valid_ref_name)."\n";
    }
    
    import subprocess
    process = subprocess.Popen(["git", "check-ref-format", ref])
    exit_status = process.wait()
    
    from pygit2 import reference_is_valid_name
    reference_is_valid_name("refs/heads/master")