What's the practice to perform a releasing with Git?
Consider to substitute the version in POM by the git describe upon build without hardcoding the version in your repository, you could do this with e.g. sed from below version_slug.

export git_version=`git describe --tags --always`
export version_slug="$(sed s/-/\./g &lt;&lt;&lt;$git_version)"


and then substitute the version_slug in pom.

In that way for each commit and/or tag in gitlab, you'll create a new version, with out actually changing the repository. 

this is what i did for a ruby project: jekyll-plantuml-url, where the version is not coded in the source, but is set upon build, and after testing deployed as the git tag.

  script:
   - bundle install
   - rake set_git_tag
   - rake
   - gem build jekyll-plantuml-url.gemspec


Furthermore don't understand the need of all those branches, with CI/CD we continuously build, test and deploy, that means before accepting a merge to master you have a deployment for QA to do the testing, code review, functional testing ...etc.

Next add QA as approver for a merge to master, thus make it mandatory that QA signs of a merge request to master and integrate quality in the development cycle or have a master that is always ready for release.

One could opt to work from master and for a release tag the master branch with a version tag, as per above example.

OR 

like gitlab does it, to create a branch for each release, cherry pick the features from master that are ready or planned and then tag the branch with a version tag.

where as a version tag creates a deployment for a commit, release or a RC.