I\'m developing a git post-receive hook in Python. Data is supplied on stdin with lines similar to
ef4d4037f8568e386629457d4d960915a85da2ae 61a4
Let's dissect the various rules and build regex parts from them:
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
(?
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
They cannot have two consecutive dots .. anywhere.
(?!.*\.\.)
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
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
They cannot begin or end with a slash / or contain multiple consecutive slashes (see the --normalize option below for an exception to this rule)
^(?!/)
(?
They cannot end with a dot ..
(?
They cannot contain a sequence @{.
(?!.*@\{)
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 ~^:?*[]+(?