@Override
  protected void performAction(
      final File repository, final File[] roots, final VCSContext context) {
    if (!canCommit(repository)) {
      return;
    }
    RepositoryInfo info = RepositoryInfo.getInstance(repository);
    final GitRepositoryState state = info.getRepositoryState();
    EventQueue.invokeLater(
        new Runnable() {
          @Override
          public void run() {

            GitUser user = null;
            try {
              GitClient client = Git.getInstance().getClient(repository);
              user = client.getUser();
            } catch (GitException ex) {
              GitClientExceptionHandler.notifyException(ex, true);
              return;
            }

            GitCommitPanel panel =
                state == GitRepositoryState.MERGING_RESOLVED
                    ? GitCommitPanelMerged.create(roots, repository, user)
                    : GitCommitPanel.create(roots, repository, user, isFromGitView(context));
            VCSCommitTable<GitFileNode> table = panel.getCommitTable();
            boolean ok = panel.open(context, new HelpCtx(CommitAction.class));

            if (ok) {
              final List<GitFileNode> commitFiles = table.getCommitFiles();

              GitModuleConfig.getDefault().setLastCanceledCommitMessage(""); // NOI18N
              panel.getParameters().storeCommitMessage();

              final VCSCommitFilter selectedFilter = panel.getSelectedFilter();
              RequestProcessor rp = Git.getInstance().getRequestProcessor(repository);
              GitProgressSupport support =
                  new CommitProgressSupport(panel, commitFiles, selectedFilter, state);
              support.start(
                  rp,
                  repository,
                  org.openide.util.NbBundle.getMessage(
                      CommitAction.class, "LBL_Commit_Progress")); // NOI18N
            } else if (!panel.getParameters().getCommitMessage().isEmpty()) {
              GitModuleConfig.getDefault()
                  .setLastCanceledCommitMessage(panel.getParameters().getCommitMessage());
            }
          }
        });
  }
 private boolean canCommit(File repository) {
   boolean commitPermitted = true;
   RepositoryInfo info = RepositoryInfo.getInstance(repository);
   GitRepositoryState state = info.getRepositoryState();
   if (!state.canCommit()) {
     commitPermitted = false;
     Map<File, GitStatus> conflicts = Collections.emptyMap();
     if (state.equals(GitRepositoryState.MERGING)) {
       try {
         GitClient client = Git.getInstance().getClient(repository);
         conflicts = client.getConflicts(new File[] {repository}, GitUtils.NULL_PROGRESS_MONITOR);
       } catch (GitException ex) {
         LOG.log(Level.INFO, null, ex);
       }
     }
     NotifyDescriptor nd;
     if (conflicts.isEmpty()) {
       nd =
           new NotifyDescriptor.Confirmation(
               NbBundle.getMessage(
                   CommitAction.class,
                   "LBL_CommitAction_CommitNotAllowed_State",
                   state.toString()), // NOI18N
               NbBundle.getMessage(CommitAction.class, "LBL_CommitAction_CannotCommit"),
               NotifyDescriptor.DEFAULT_OPTION,
               NotifyDescriptor.ERROR_MESSAGE); // NOI18N
     } else {
       nd =
           new NotifyDescriptor.Confirmation(
               NbBundle.getMessage(
                   CommitAction.class, "LBL_CommitAction_CommitNotAllowed_Conflicts"), // NOI18N
               NbBundle.getMessage(CommitAction.class, "LBL_CommitAction_CannotCommit"),
               NotifyDescriptor.YES_NO_OPTION,
               NotifyDescriptor.QUESTION_MESSAGE); // NOI18N
     }
     Object retval = DialogDisplayer.getDefault().notify(nd);
     if (retval == NotifyDescriptor.YES_OPTION) {
       GitUtils.openInVersioningView(
           conflicts.keySet(), repository, GitUtils.NULL_PROGRESS_MONITOR);
     }
   }
   return commitPermitted;
 }