@Test
  public void updateKeepsWorkingAfterPull() throws Exception {

    changeFile_A_AndCommitInRemoteRepository();

    // do a simple pull without an update
    HgPullCommand pull = new HgPullCommand(myProject, projectRepoVirtualFile);
    pull.setSource(HgUtil.getRepositoryDefaultPath(myProject, projectRepoVirtualFile));
    pull.setUpdate(false);
    pull.execute();

    assertEquals(
        determineNumberOfIncomingChanges(projectRepo),
        0,
        "The update operation should have pulled the incoming changes from the default repository.");

    updateThroughPlugin();

    HgRevisionNumber parentRevision =
        new HgWorkingCopyRevisionsCommand(myProject).firstParent(projectRepoVirtualFile);
    assertEquals(
        parentRevision.getRevision(),
        "1",
        "The working directory should have been updated to the latest version");
  }
 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();
 }
  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;
  }