How do I check for valid Git branch names?

前端 未结 6 1691
粉色の甜心
粉色の甜心 2021-01-03 23:40

I\'m developing a git post-receive hook in Python. Data is supplied on stdin with lines similar to

ef4d4037f8568e386629457d4d960915a85da2ae 61a4         


        
6条回答
  •  悲哀的现实
    2021-01-04 00:17

    Let's dissect the various rules and build regex parts from them:

    1. They can include slash / for hierarchical (directory) grouping, but no slash-separated component can begin with a dot . or end with the sequence .lock.

       # must not contain /.
       (?!.*/\.)
       # must not end with .lock
       (?
    2. They must contain at least one /. This enforces the presence of a category like heads/, tags/ etc. but the actual names are not restricted. If the --allow-onelevel option is used, this rule is waived.

       .+/.+  # may get more precise later
      
    3. They cannot have two consecutive dots .. anywhere.

       (?!.*\.\.)
      
    4. They cannot have ASCII control characters (i.e. bytes whose values are lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : anywhere.

       [^\000-\037\177 ~^:]+   # pattern for allowed characters
      
    5. They cannot have question-mark ?, asterisk *, or open bracket [ anywhere. See the --refspec-pattern option below for an exception to this rule.

       [^\000-\037\177 ~^:?*[]+   # new pattern for allowed characters
      
    6. They cannot begin or end with a slash / or contain multiple consecutive slashes (see the --normalize option below for an exception to this rule)

       ^(?!/)
       (?
    7. They cannot end with a dot ..

       (?
    8. They cannot contain a sequence @{.

       (?!.*@\{)
      
    9. They cannot contain a \.

       (?!.*\\)
      

    Piecing it all together we arrive at the following monstrosity:

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

    And if you want to exclude those that start with build- then just add another lookahead:

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

    This can be optimized a bit as well by conflating a few things that look for common patterns:

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

提交回复
热议问题