docs: @Override
      public void execute() throws MojoExecutionException, MojoFailureException {
          validateConfiguration();
  
          try {
              // set git flow configuration
              initGitFlowConfig();
  
              // check uncommitted changes
              checkUncommittedChanges();
  
              // git for-each-ref --count=1 refs/heads/release/*
              final String releaseBranch = gitFindBranches(
                      gitFlowConfig.getReleaseBranchPrefix(), true);
  
              if (StringUtils.isNotBlank(releaseBranch)) {
                  throw new MojoFailureException(
                          "Release branch already exists. Cannot start release.");
              }
  
              if (fetchRemote) {
                  // checkout from remote if doesn't exist
                  gitFetchRemoteAndCreate(gitFlowConfig.getDevelopmentBranch());
  
                  // fetch and check remote
                  gitFetchRemoteAndCompare(gitFlowConfig.getDevelopmentBranch());
              }
  
              final String startPoint;
              if (StringUtils.isNotBlank(fromCommit) && notSameProdDevName()) {
                  startPoint = fromCommit;
              } else {
                  startPoint = gitFlowConfig.getDevelopmentBranch();
              }
  
              // need to be in develop to check snapshots and to get
              // correct project version
              gitCheckout(startPoint);
  
              // check snapshots dependencies
              if (!allowSnapshots) {
                  checkSnapshotDependencies();
              }
  
              if (commitDevelopmentVersionAtStart && !notSameProdDevName()) {
                  getLog().warn(
                          "The commitDevelopmentVersionAtStart will not have effect. It can be enabled only when there are separate branches for development and production.");
                  commitDevelopmentVersionAtStart = false;
              }
  
              // get release version
              final String releaseVersion = getReleaseVersion();
  
              // get release branch
              String branchName = gitFlowConfig.getReleaseBranchPrefix();
              if (!sameBranchName) {
                  branchName += releaseVersion;
              }
  
              String projectVersion = releaseVersion;
              if (useSnapshotInRelease && !ArtifactUtils.isSnapshot(projectVersion)) {
                  projectVersion = projectVersion + "-" + Artifact.SNAPSHOT_VERSION;
              }
  
              if (useSnapshotInRelease && mavenSession.getUserProperties().get("useSnapshotInRelease") != null) {
                  getLog().warn(
                          "The useSnapshotInRelease parameter is set from the command line. Don't forget to use it in the finish goal as well."
                                  + " It is better to define it in the project's pom file.");
              }
  
              if (commitDevelopmentVersionAtStart) {
                  // mvn versions:set ...
                  // git commit -a -m ...
                  commitProjectVersion(projectVersion,
                          commitMessages.getReleaseStartMessage()); 
  
                  // git branch release/... develop
                  gitCreateBranch(branchName, startPoint);
  
                  final String nextSnapshotVersion =
                          getNextSnapshotVersion(releaseVersion);
  
                  // mvn versions:set ...
                  // git commit -a -m ...
                  commitProjectVersion(nextSnapshotVersion, commitMessages.getReleaseVersionUpdateMessage());
  
                  // git checkout release/...
                  gitCheckout(branchName);
              } else {
                  // git checkout -b release/... develop
                  gitCreateAndCheckout(branchName, startPoint);
  
                  // mvn versions:set ...
                  // git commit -a -m ...
                  commitProjectVersion(projectVersion,
                          commitMessages.getReleaseStartMessage());
              }
  
              if (installProject) {
                  // mvn clean install
                  mvnCleanInstall();
              }
  
              if (pushRemote) {
                  if (commitDevelopmentVersionAtStart) {
                      gitPush(gitFlowConfig.getDevelopmentBranch(), false);
                  }
  
                  gitPush(branchName, false);
              }
          } catch (CommandLineException e) {
              throw new MojoFailureException("release-start", e);
          } catch (VersionParseException e) {
              throw new MojoFailureException("release-start", e);
          }
      }