/**
   * Checks if update is possible, saves local changes and updates all roots. In case of error shows
   * notification and returns false. If update completes without errors, returns true.
   *
   * <p>Perform update on all roots. 0. Blocks reloading project on external change, saving/syncing
   * on frame deactivation. 1. Checks if update is possible (rebase/merge in progress, no tracked
   * branches...) and provides merge dialog to solve problems. 2. Finds updaters to use (merge or
   * rebase). 3. Preserves local changes if needed (not needed for merge sometimes). 4. Updates via
   * 'git pull' or equivalent. 5. Restores local changes if update completed or failed with error.
   * If update is incomplete, i.e. some unmerged files remain, local changes are not restored.
   */
  @NotNull
  public GitUpdateResult update(final UpdateMethod updateMethod) {
    LOG.info("update started|" + updateMethod);
    String oldText = myProgressIndicator.getText();
    myProgressIndicator.setText("Updating...");

    for (GitRepository repository : myRepositories) {
      repository.update();
    }

    // check if update is possible
    if (checkRebaseInProgress()
        || isMergeInProgress()
        || areUnmergedFiles()
        || !checkTrackedBranchesConfigured()) {
      return GitUpdateResult.NOT_READY;
    }

    if (!fetchAndNotify()) {
      return GitUpdateResult.NOT_READY;
    }

    AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject);
    GitUpdateResult result;
    try {
      result = updateImpl(updateMethod);
    } finally {
      DvcsUtil.workingTreeChangeFinished(myProject, token);
    }
    myProgressIndicator.setText(oldText);
    return result;
  }
  private boolean stash() {
    if (!mySyncResult.hasLocalRepository()) {
      LOG.error("unexpected null local repro in call to stash");
      return false;
    }

    final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
    if (changeListManager.isFreezedWithNotification("Can not stash changes now")) return false;

    final GitLineHandler handler =
        new GitLineHandler(myProject, mySourceRepository.getRoot(), GitCommand.STASH);
    handler.addParameters("save");
    handler.addParameters("--keep-index");
    String date =
        DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date());
    myStashMessage =
        "Cloud Debugger saved changes from branch " + myOriginalBranchName + " at " + date;
    handler.addParameters(myStashMessage);
    AccessToken token = DvcsUtil.workingTreeChangeStarted(myProject);
    try {
      GitHandlerUtil.doSynchronously(
          handler, GitBundle.getString("stashing.title"), handler.printableCommandLine());
    } finally {
      DvcsUtil.workingTreeChangeFinished(myProject, token);
    }
    return true;
  }