/**
  * @param fetchAll Pass {@code true} to fetch all remotes and all branches (like {@code git fetch}
  *     without parameters does). Pass {@code false} to fetch only the tracked branch of the
  *     current branch.
  */
 public GitFetcher(
     @NotNull Project project, @NotNull ProgressIndicator progressIndicator, boolean fetchAll) {
   myProject = project;
   myProgressIndicator = progressIndicator;
   myFetchAll = fetchAll;
   myRepositoryManager = GitUtil.getRepositoryManager(myProject);
   myVcs = GitVcs.getInstance(project);
 }
  private GitFetchResult fetchNatively(
      @NotNull VirtualFile root, @NotNull GitRemote remote, @Nullable String branch) {
    final GitLineHandlerPasswordRequestAware h =
        new GitLineHandlerPasswordRequestAware(myProject, root, GitCommand.FETCH);
    h.addProgressParameter();
    if (GitVersionSpecialty.SUPPORTS_FETCH_PRUNE.existsIn(myVcs.getVersion())) {
      h.addParameters("--prune");
    }

    String remoteName = remote.getName();
    h.addParameters(remoteName);
    if (branch != null) {
      h.addParameters(getFetchSpecForBranch(branch, remoteName));
    }

    final GitTask fetchTask = new GitTask(myProject, h, "Fetching " + remote.getFirstUrl());
    fetchTask.setProgressIndicator(myProgressIndicator);
    fetchTask.setProgressAnalyzer(new GitStandardProgressAnalyzer());

    GitFetchPruneDetector pruneDetector = new GitFetchPruneDetector();
    h.addLineListener(pruneDetector);

    final AtomicReference<GitFetchResult> result = new AtomicReference<GitFetchResult>();
    fetchTask.execute(
        true,
        false,
        new GitTaskResultHandlerAdapter() {
          @Override
          protected void onSuccess() {
            result.set(GitFetchResult.success());
          }

          @Override
          protected void onCancel() {
            LOG.info("Cancelled fetch.");
            result.set(GitFetchResult.cancel());
          }

          @Override
          protected void onFailure() {
            LOG.info("Error fetching: " + h.errors());
            if (!h.hadAuthRequest()) {
              myErrors.addAll(h.errors());
            } else {
              myErrors.add(new VcsException("Authentication failed"));
            }
            result.set(GitFetchResult.error(myErrors));
          }
        });

    result.get().addPruneInfo(pruneDetector.getPrunedRefs());
    return result.get();
  }
 public static void displayFetchResult(
     @NotNull Project project,
     @NotNull GitFetchResult result,
     @Nullable String errorNotificationTitle,
     @NotNull Collection<? extends Exception> errors) {
   if (result.isSuccess()) {
     GitVcs.NOTIFICATION_GROUP_ID
         .createNotification(
             "Fetched successfully" + result.getAdditionalInfo(), NotificationType.INFORMATION)
         .notify(project);
   } else if (result.isCancelled()) {
     GitVcs.NOTIFICATION_GROUP_ID
         .createNotification(
             "Fetch cancelled by user" + result.getAdditionalInfo(), NotificationType.WARNING)
         .notify(project);
   } else if (result.isNotAuthorized()) {
     String title;
     String description;
     if (errorNotificationTitle != null) {
       title = errorNotificationTitle;
       description = "Fetch failed: couldn't authorize";
     } else {
       title = "Fetch failed";
       description = "Couldn't authorize";
     }
     description += result.getAdditionalInfo();
     GitUIUtil.notifyMessage(project, title, description, NotificationType.ERROR, true, null);
   } else {
     GitVcs instance = GitVcs.getInstance(project);
     if (instance != null && instance.getExecutableValidator().isExecutableValid()) {
       GitUIUtil.notifyMessage(
           project,
           "Fetch failed",
           result.getAdditionalInfo(),
           NotificationType.ERROR,
           true,
           errors);
     }
   }
 }