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);
 }
 private void abortOnMultipleLocalHeads(List<HgRevisionNumber> originalBranchHeadsRemaining)
     throws VcsException {
   if (originalBranchHeadsRemaining.size() != 1) {
     throw new VcsException(
         HgVcsMessages.message(
             "hg4idea.update.error.merge.multipleLocalHeads", repoRoot.getPath()));
   }
 }
 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()));
   }
 }
 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();
 }
 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()));
   }
 }
  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);
  }
  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);
  }
  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;
  }
 private void abortOnLocalChanges() throws VcsException {
   if (getLocalChanges().size() != 0) {
     throw new VcsException(
         HgVcsMessages.message("hg4idea.update.error.localchanges", repoRoot.getPath()));
   }
 }