Home > Back-end >  Regex for git branch naming
Regex for git branch naming

Time:04-04

I am looking for a regex to enforce a valid git branch naming convention.

Rules are

  1. A branch name can only be main, master, development
  2. A branch name can start with features, tests, bugfix, hotfix; followed by / description, number, -, _ (or nesting of it but max allowed in upto 2)
  3. A branch name can start with release/ then version number, and it can have beta, alpha or rc tag with or without number.

Here are the example of few valid name

main
bugfix/user-list
bugfix/user_list
bugfix/123
bugfix/123/account-update
bugfix/123/account_update
bugfix/User_crud/account-update
bugfix/User_crud/account_update
tests/api
tests/123
tests/123/hello
release/1.0.1
release/1.0.1-beta1
release/1.0.1-beta
release/1.0.1-rc3

I had written this regex (https://regex101.com/r/n0CAuM/1), but it is not matching all the above example

^(development|master|main|(((features|tests|bugfix|hotfix)\/(([0-9A-Za-z-_] )|((\/[0-9A-Za-z-_] )))|release\/(?:(\d )\.)?(?:(\d )\.)?(\d )?(-(alpha|beta|rc)[0-9]))))

Also note as I will be using the regex in a bash script which only support POSIX regex engine.

CodePudding user response:

You can put the alternations for all 3 parts in their own part of the pattern.

For the groupings, instead of a non capture group you can use a capture group, and for the digits use [0-9] instead of \d.

If there is maximum of 1-2 parts, you can use a quantifier {1,2}

You could write the pattern as:

^(main|development|master|(features|tests|(bug|hot)fix)(\/[a-zA-Z0-9] ([-_][a-zA-Z0-9] )*){1,2}|release\/[0-9] (\.[0-9] )*(-(alpha|beta|rc)[0-9]*)?)$
  • ^ Start of string
  • ( Start outer grouping to match 1 of the 3 allowed patterns
    • main|development|master Match 1 of the single named alternatives
    • | Or
    • (features|tests|(bug|hot)fix)(\/[a-zA-Z0-9] ([-_][a-zA-Z0-9] )*){1,2} Match a variation for features, tests and fixes a following with / and not starting with - or _ and repeat that part 1 or 2 times
    • | Or
    • release\/[0-9] (\.[0-9] )*(-(alpha|beta|rc)[0-9]*)? Match a variation for the release branch with optional alpha, beta or rc
  • ) Close outer grouping
  • $ End of string

See a regex demo and a Bash demo.

Example

array=(development main bugfix/user-list bugfix/user_list bugfix/123 bugfix/123/account-update bugfix/123/account_update bugfix/User_crud/account-update bugfix/User_crud/account_update tests/api tests/123 tests/123/hello release/1.0.1 release/1.0.1-beta1 release/1.0.1-beta release/1.0.1-rc3 bugfix/ bugfix/- bugfix/_ bugfix/-name bugfix/_name bugfix/-/name bugfix/-/- bugfix/-/_ release/v1.0.1)

for i in "${array[@]}"
do
    if [[ "$i" =~ ^(main|development|master|(features|tests|(bug|hot)fix)(/[a-zA-Z0-9] ([-_][a-zA-Z0-9] )*){1,2}|release/[0-9] (\.[0-9] )*(-(alpha|beta|rc)[0-9]*)?)$ ]]; then
      echo "Match: "$i
  else
      echo "No match: "$i
  fi
done

Output

Match: development
Match: main
Match: bugfix/user-list
Match: bugfix/user_list
Match: bugfix/123
Match: bugfix/123/account-update
Match: bugfix/123/account_update
Match: bugfix/User_crud/account-update
Match: bugfix/User_crud/account_update
Match: tests/api
Match: tests/123
Match: tests/123/hello
Match: release/1.0.1
Match: release/1.0.1-beta1
Match: release/1.0.1-beta
Match: release/1.0.1-rc3
No match: bugfix/
No match: bugfix/-
No match: bugfix/_
No match: bugfix/-name
No match: bugfix/_name
No match: bugfix/-/name
No match: bugfix/-/-
No match: bugfix/-/_
No match: release/v1.0.1
  • Related