コード例 #1
0
  @NotNull
  public static <CommitInfo> List<CommitInfo> getCommitRecords(
      @NotNull Project project,
      @Nullable HgCommandResult result,
      @NotNull Function<String, CommitInfo> converter,
      boolean silent) {
    final List<CommitInfo> revisions = new LinkedList<CommitInfo>();
    if (result == null) {
      return revisions;
    }

    List<String> errors = result.getErrorLines();
    if (errors != null && !errors.isEmpty()) {
      if (result.getExitValue() != 0) {
        if (silent) {
          LOG.warn(errors.toString());
        } else {
          VcsNotifier.getInstance(project)
              .notifyError(
                  HgVcsMessages.message("hg4idea.error.log.command.execution"), errors.toString());
        }
        return Collections.emptyList();
      }
      LOG.warn(errors.toString());
    }
    String output = result.getRawOutput();
    List<String> changeSets = StringUtil.split(output, HgChangesetUtil.CHANGESET_SEPARATOR);
    return ContainerUtil.mapNotNull(changeSets, converter);
  }
コード例 #2
0
 private HgCommandResult doMerge(ProgressIndicator indicator) throws VcsException {
   indicator.setText2(HgVcsMessages.message("hg4idea.update.progress.merging"));
   HgMergeCommand mergeCommand = new HgMergeCommand(project, repoRoot);
   // do not explicitly set the revision, that way mercurial itself checks that there are exactly
   // two heads in this branch
   //    mergeCommand.setRevision(headToMerge.getRevision());
   return new HgHeadMerger(project, mergeCommand).merge(repoRoot);
 }
コード例 #3
0
 private void abortOnMultipleLocalHeads(List<HgRevisionNumber> originalBranchHeadsRemaining)
     throws VcsException {
   if (originalBranchHeadsRemaining.size() != 1) {
     throw new VcsException(
         HgVcsMessages.message(
             "hg4idea.update.error.merge.multipleLocalHeads", repoRoot.getPath()));
   }
 }
コード例 #4
0
 private void abortOnMultiplePulledHeads(List<HgRevisionNumber> newBranchHeadsAfterPull)
     throws VcsException {
   if (newBranchHeadsAfterPull.size() != 1) {
     throw new VcsException(
         HgVcsMessages.message(
             "hg4idea.update.error.merge.multipleRemoteHeads",
             newBranchHeadsAfterPull.size(),
             repoRoot.getPath()));
   }
 }
コード例 #5
0
 private HgCommandExitCode pull(VirtualFile repo, ProgressIndicator indicator, boolean isRebase)
     throws VcsException {
   indicator.setText2(HgVcsMessages.message("hg4idea.progress.pull.with.update"));
   HgPullCommand hgPullCommand = new HgPullCommand(project, repo);
   final String defaultPath = HgUtil.getRepositoryDefaultPath(project, repo);
   hgPullCommand.setSource(defaultPath);
   if (isRebase) {
     hgPullCommand.setRebase(true);
   } else {
     hgPullCommand.setUpdate(true);
   }
   return hgPullCommand.execute();
 }
コード例 #6
0
 @NotNull
 public static List<HgTagBranch> getBranches(@NotNull Project project, @NotNull VirtualFile root) {
   HgCommandResult branchesResult = new HgTagBranchCommand(project, root).collectBranches();
   if (branchesResult == null) {
     new HgCommandResultNotifier(project)
         .notifyError(
             branchesResult,
             "Mercurial command failed",
             HgVcsMessages.message("hg4idea.branches.error.description"));
     return Collections.emptyList();
   }
   return HgTagBranchCommand.parseResult(branchesResult);
 }
コード例 #7
0
 public HgExecutableValidator(Project project) {
   super(project, HgVcs.NOTIFICATION_GROUP_ID);
   myVcs = HgVcs.getInstance(project);
   setMessagesAndTitles(
       HgVcsMessages.message("hg4idea.executable.notification.title"),
       HgVcsMessages.message("hg4idea.executable.notification.description"),
       HgVcsMessages.message("hg4idea.executable.dialog.title"),
       HgVcsMessages.message("hg4idea.executable.dialog.description"),
       HgVcsMessages.message("hg4idea.executable.dialog.error"),
       HgVcsMessages.message("hg4idea.executable.filechooser.title"),
       HgVcsMessages.message("hg4idea.executable.filechooser.description"));
 }
コード例 #8
0
 private void commitOrWarnAboutConflicts(
     List<VcsException> exceptions, HgCommandResult mergeResult) throws VcsException {
   if (mergeResult.getExitValue() == 0) { // operation successful and no conflicts
     try {
       new HgCommitCommand(project, repoRoot, "Automated merge").execute();
     } catch (HgCommandException e) {
       throw new VcsException(e);
     }
   } else {
     reportWarning(
         exceptions,
         HgVcsMessages.message("hg4idea.update.warning.merge.conflicts", repoRoot.getPath()));
   }
 }
コード例 #9
0
public class HgProjectConfigurable implements SearchableConfigurable {

  public static final String DISPLAY_NAME = HgVcsMessages.message("hg4idea.mercurial");

  private final HgConfigurationProjectPanel myPanel;
  @NotNull private final Project myProject;

  public HgProjectConfigurable(@NotNull Project project, HgProjectSettings projectSettings) {
    myProject = project;
    myPanel = new HgConfigurationProjectPanel(projectSettings, myProject);
  }

  @Nls
  public String getDisplayName() {
    return DISPLAY_NAME;
  }

  public String getHelpTopic() {
    return "project.propVCSSupport.VCSs.Mercurial";
  }

  public JComponent createComponent() {
    return myPanel.getPanel();
  }

  public boolean isModified() {
    return myPanel.isModified();
  }

  public void apply() throws ConfigurationException {
    myPanel.saveSettings();
    if (myPanel.getProjectSettings().isCheckIncomingOutgoing()) {
      myProject.getMessageBus().syncPublisher(HgVcs.INCOMING_OUTGOING_CHECK_TOPIC).show();
    } else {
      myProject.getMessageBus().syncPublisher(HgVcs.INCOMING_OUTGOING_CHECK_TOPIC).hide();
    }
  }

  public void reset() {
    myPanel.loadSettings();
  }

  public void disposeUIResources() {}

  @NotNull
  public String getId() {
    return "Mercurial.Project";
  }
}
コード例 #10
0
  private void updateToPulledHead(
      VirtualFile repo,
      UpdatedFiles updatedFiles,
      HgRevisionNumber newHead,
      ProgressIndicator indicator) {
    indicator.setText2(HgVcsMessages.message("hg4idea.update.progress.updating.to.pulled.head"));
    HgRevisionNumber parentBeforeUpdate =
        new HgWorkingCopyRevisionsCommand(project).firstParent(repo);
    HgUpdateCommand updateCommand = new HgUpdateCommand(project, repoRoot);
    updateCommand.setRevision(newHead.getChangeset());
    updateCommand.setClean(true);
    updateCommand.execute();

    HgRevisionNumber commonParent = findCommonParent(newHead, parentBeforeUpdate);
    addUpdatedFiles(repo, updatedFiles, commonParent, newHead);
  }
コード例 #11
0
  private void update(
      @NotNull VirtualFile repo,
      ProgressIndicator indicator,
      UpdatedFiles updatedFiles,
      List<VcsException> warnings)
      throws VcsException {
    indicator.setText2(HgVcsMessages.message("hg4idea.progress.updatingworkingdir"));

    HgRevisionNumber parentBeforeUpdate =
        new HgWorkingCopyRevisionsCommand(project).firstParent(repo);
    HgUpdateCommand hgUpdateCommand = new HgUpdateCommand(project, repo);
    String warningMessages = ensureSuccess(hgUpdateCommand.execute()).getWarnings();
    handlePossibleWarning(warnings, warningMessages);

    HgRevisionNumber parentAfterUpdate =
        new HgWorkingCopyRevisionsCommand(project).firstParent(repo);

    addUpdatedFiles(repo, updatedFiles, parentBeforeUpdate, parentAfterUpdate);
  }
コード例 #12
0
 public String getDisplayName() {
   return HgVcsMessages.message("hg4idea.mercurial");
 }
コード例 #13
0
 /**
  * Checks Hg version and updates the myVersion variable. In the case of nullable or unsupported
  * version reports the problem.
  */
 public void checkVersion() {
   final String executable = getGlobalSettings().getHgExecutable();
   HgCommandResultNotifier errorNotification = new HgCommandResultNotifier(myProject);
   final String SETTINGS_LINK = "settings";
   final String UPDATE_LINK = "update";
   NotificationListener linkAdapter =
       new NotificationListener.Adapter() {
         @Override
         protected void hyperlinkActivated(
             @NotNull Notification notification, @NotNull HyperlinkEvent e) {
           if (SETTINGS_LINK.equals(e.getDescription())) {
             ShowSettingsUtil.getInstance()
                 .showSettingsDialog(myProject, getConfigurable().getDisplayName());
           } else if (UPDATE_LINK.equals(e.getDescription())) {
             BrowserUtil.browse("http://mercurial.selenic.com");
           }
         }
       };
   try {
     myVersion = HgVersion.identifyVersion(executable);
     // if version is not supported, but have valid hg executable
     if (!myVersion.isSupported()) {
       LOG.info("Unsupported Hg version: " + myVersion);
       String message =
           String.format(
               "The <a href='"
                   + SETTINGS_LINK
                   + "'>configured</a> version of Hg is not supported: %s.<br/> "
                   + "The minimal supported version is %s. Please <a href='"
                   + UPDATE_LINK
                   + "'>update</a>.",
               myVersion,
               HgVersion.MIN);
       errorNotification.notifyError(null, "Unsupported Hg version", message, linkAdapter);
     } else if (myVersion.hasUnsupportedExtensions()) {
       String unsupportedExtensionsAsString = myVersion.getUnsupportedExtensions().toString();
       LOG.warn("Unsupported Hg extensions: " + unsupportedExtensionsAsString);
       String message =
           String.format(
               "Some hg extensions %s are not found or not supported by your hg version and will be ignored.\n"
                   + "Please, update your hgrc or Mercurial.ini file",
               unsupportedExtensionsAsString);
       errorNotification.notifyWarning("Unsupported Hg version", message);
     }
   } catch (Exception e) {
     if (getExecutableValidator().checkExecutableAndNotifyIfNeeded()) {
       // sometimes not hg application has version command, but we couldn't parse an answer as
       // valid hg,
       // so parse(output) throw ParseException, but hg and git executable seems to be valid in
       // this case
       final String reason = (e.getCause() != null ? e.getCause() : e).getMessage();
       String message = HgVcsMessages.message("hg4idea.unable.to.run.hg", executable);
       errorNotification.notifyError(
           null,
           message,
           String.format(
               reason
                   + "<br/> Please check your hg executable path in <a href='"
                   + SETTINGS_LINK
                   + "'> settings </a>"),
           linkAdapter);
     }
   }
 }
コード例 #14
0
  public boolean update(
      final UpdatedFiles updatedFiles, ProgressIndicator indicator, List<VcsException> warnings)
      throws VcsException {
    indicator.setText(HgVcsMessages.message("hg4idea.progress.updating", repoRoot.getPath()));

    String defaultPath = HgUtil.getRepositoryDefaultPath(project, repoRoot);

    if (StringUtil.isEmptyOrSpaces(defaultPath)) {
      throw new VcsException(
          HgVcsMessages.message("hg4idea.warning.no-default-update-path", repoRoot.getPath()));
    }

    List<HgRevisionNumber> branchHeadsBeforePull = new HgHeadsCommand(project, repoRoot).execute();

    if (branchHeadsBeforePull.size() > 1) {
      reportWarning(
          warnings,
          HgVcsMessages.message(
              "hg4idea.update.warning.multipleHeadsBeforeUpdate", repoRoot.getPath()));
    }

    // TODO perhaps report a warning in this case ?
    //    //if the parent of the working dir is not the tip of the current branch, the user has
    //    //manually brought his working copy to some specific revision. In that case we won't touch
    //    //his setup
    //    if (!parentRevision.equals(currentBranchHead)) {
    //      throw new VcsException("working dir not at branch tip (use \"Update to...\" to check out
    // branch tip)");
    //    }

    HgRevisionNumber parentBeforeUpdate =
        new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot);
    HgCommandExitCode pullResult = pull(repoRoot, indicator, shouldRebase());
    if (pullResult == HgCommandExitCode.ERROR) {
      return false;
    }

    if (pullResult == HgCommandExitCode.SUCCESS) {
      HgRevisionNumber parentAfterUpdate =
          new HgWorkingCopyRevisionsCommand(project).firstParent(repoRoot);
      addUpdatedFiles(repoRoot, updatedFiles, parentBeforeUpdate, parentAfterUpdate);
      return true;
    }

    if (shouldMerge()) {

      indicator.setText2(HgVcsMessages.message("hg4idea.progress.countingHeads"));

      List<HgRevisionNumber> branchHeadsAfterPull = new HgHeadsCommand(project, repoRoot).execute();
      List<HgRevisionNumber> pulledBranchHeads =
          determinePulledBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);
      List<HgRevisionNumber> remainingOriginalBranchHeads =
          determingRemainingOriginalBranchHeads(branchHeadsBeforePull, branchHeadsAfterPull);

      if (branchHeadsAfterPull.size() > 1) {
        abortOnLocalChanges();
        abortOnMultiplePulledHeads(pulledBranchHeads);
        abortOnMultipleLocalHeads(remainingOriginalBranchHeads);

        HgCommandResult mergeResult = doMerge(indicator);

        if (shouldCommitAfterMerge()) {
          commitOrWarnAboutConflicts(warnings, mergeResult);
        }
      }
      // any kind of update could have resulted in merges and merge conflicts, so run the resolver
      resolvePossibleConflicts(updatedFiles);
    } else {
      processRebase(updatedFiles);
    }

    return true;
  }
コード例 #15
0
 private void abortOnLocalChanges() throws VcsException {
   if (getLocalChanges().size() != 0) {
     throw new VcsException(
         HgVcsMessages.message("hg4idea.update.error.localchanges", repoRoot.getPath()));
   }
 }