@NotNull
 private GitFetchResult fetchAll(
     @NotNull GitRepository repository, @NotNull GitFetchResult fetchResult) {
   for (GitRemote remote : repository.getRemotes()) {
     String url = remote.getFirstUrl();
     if (url == null) {
       LOG.error("URL is null for remote " + remote.getName());
       continue;
     }
     if (GitHttpAdapter.shouldUseJGit(url)) {
       GitFetchResult res = GitHttpAdapter.fetch(repository, remote, url, null);
       res.addPruneInfo(fetchResult.getPrunedRefs());
       fetchResult = res;
       myErrors.addAll(fetchResult.getErrors());
       if (!fetchResult.isSuccess()) {
         break;
       }
     } else {
       GitFetchResult res = fetchNatively(repository.getRoot(), remote, null);
       res.addPruneInfo(fetchResult.getPrunedRefs());
       fetchResult = res;
       if (!fetchResult.isSuccess()) {
         break;
       }
     }
   }
   return fetchResult;
 }
  @NotNull
  private static FetchParams getFetchParams(@NotNull GitRepository repository) {
    GitLocalBranch currentBranch = repository.getCurrentBranch();
    if (currentBranch == null) {
      // fetching current branch is called from Update Project and Push, where branch tracking is
      // pre-checked
      String message = "Current branch can't be null here. \nRepository: " + repository;
      LOG.error(message);
      return new FetchParams(GitFetchResult.error(new Exception(message)));
    }
    GitBranchTrackInfo trackInfo = GitBranchUtil.getTrackInfoForBranch(repository, currentBranch);
    if (trackInfo == null) {
      String message =
          "Tracked info is null for branch " + currentBranch + "\n Repository: " + repository;
      LOG.error(message);
      return new FetchParams(GitFetchResult.error(new Exception(message)));
    }

    GitRemote remote = trackInfo.getRemote();
    String url = remote.getFirstUrl();
    if (url == null) {
      String message = "URL is null for remote " + remote.getName();
      LOG.error(message);
      return new FetchParams(GitFetchResult.error(new Exception(message)));
    }

    return new FetchParams(remote, trackInfo.getRemoteBranch(), url);
  }
 @NotNull
 private static Collection<String> getRemoteNames(@NotNull GitRepository repository) {
   Collection<String> names = new ArrayList<String>(repository.getRemotes().size());
   for (GitRemote remote : repository.getRemotes()) {
     names.add(remote.getName());
   }
   return names;
 }
 public void addOrResetGitRemote(CloudGitApplication application, GitRepository repository)
     throws ServerRuntimeException {
   GitRemote gitRemote = GitUtil.findRemoteByName(repository, getRemoteName());
   if (gitRemote == null) {
     addGitRemote(application);
   } else if (!gitRemote.getUrls().contains(application.getGitUrl())) {
     resetGitRemote(application);
   }
 }
 @Nullable
 public static GitRemote getDefaultRemote(@NotNull Collection<GitRemote> remotes) {
   for (GitRemote remote : remotes) {
     if (remote.getName().equals(GitRemote.ORIGIN_NAME)) {
       return remote;
     }
   }
   return null;
 }
 @Nullable
 public static GitRemote findOrigin(Collection<GitRemote> remotes) {
   for (GitRemote remote : remotes) {
     if (remote.getName().equals("origin")) {
       return remote;
     }
   }
   return null;
 }
 public void selectRemote(@NotNull String remoteName) {
   for (GitRemote remote : myRemotes) {
     if (remote.getName().equals(remoteName)) {
       myRemoteCombobox.setSelectedItem(remote);
       return;
     }
   }
   myRemoteCombobox.setSelectedIndex(0);
 }
 @Nullable
 private static GitRemote getRemoteByName(
     @NotNull GitRepository repository, @NotNull String remoteName) {
   for (GitRemote remote : repository.getRemotes()) {
     if (remote.getName().equals(remoteName)) {
       return remote;
     }
   }
   return null;
 }
 @Nullable
 static String findGithubRemoteUrl(@NotNull GitRepository repository) {
   for (GitRemote remote : repository.getRemotes()) {
     for (String url : remote.getUrls()) {
       if (isGithubUrl(url)) {
         return url;
       }
     }
   }
   return null;
 }
  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();
  }
 private void doLoadForksFromGit(@NotNull ProgressIndicator indicator) {
   for (GitRemote remote : myGitRepository.getRemotes()) {
     for (String url : remote.getUrls()) {
       if (GithubUrlUtil.isGithubUrl(url)) {
         GithubFullPath path = GithubUrlUtil.getUserAndRepositoryFromRemoteUrl(url);
         if (path != null) {
           doAddFork(path, remote.getName(), indicator);
           break;
         }
       }
     }
   }
 }
 @Override
 @NotNull
 public GitCommandResult push(
     @NotNull GitRepository repository,
     @NotNull GitPushSpec pushSpec,
     @NotNull GitLineHandlerListener... listeners) {
   GitRemote remote = pushSpec.getRemote();
   GitBranch remoteBranch = pushSpec.getDest();
   String destination = remoteBranch.getName().replaceFirst(remote.getName() + "/", "");
   return push(
       repository,
       remote.getName(),
       pushSpec.getSource().getName() + ":" + destination,
       listeners);
 }
 @NotNull
 public GitFetchResult fetch(@NotNull VirtualFile root, @NotNull String remoteName) {
   GitRepository repository = myRepositoryManager.getRepositoryForRoot(root);
   if (repository == null) {
     return logError("Repository can't be null for " + root, myRepositoryManager.toString());
   }
   GitRemote remote = GitUtil.findRemoteByName(repository, remoteName);
   if (remote == null) {
     return logError("Couldn't find remote with the name " + remoteName, null);
   }
   String url = remote.getFirstUrl();
   if (url == null) {
     return logError("URL is null for remote " + remote.getName(), null);
   }
   return fetchRemote(repository, remote, url);
 }
  /**
   * This method for now assumes the default branch name is master
   *
   * <p>If there is no master, return the first branch on the list or null for empty list
   *
   * <p>We should get the default branch from TF if necessary, but that's a server call
   */
  @Nullable
  private GitRemoteBranch getDefaultBranch(@NotNull final List<GitRemoteBranch> remoteBranches) {
    assert remoteBranches != null;
    if (remoteBranches.isEmpty() || this.tfGitRemotes.isEmpty()) {
      return null;
    }

    final GitRemote firstTfRemote = this.tfGitRemotes.iterator().next();

    final String masterBranchName = String.format("%s/master", firstTfRemote.getName());
    for (GitRemoteBranch remoteBranch : remoteBranches) {
      if (remoteBranch.getName().equals(masterBranchName)) {
        return remoteBranch;
      }
    }

    return remoteBranches.get(0);
  }
 @NotNull
 public static Collection<GitRemote> getRemotesWithCommonNames(
     @NotNull Collection<GitRepository> repositories) {
   if (repositories.isEmpty()) {
     return Collections.emptyList();
   }
   Iterator<GitRepository> iterator = repositories.iterator();
   List<GitRemote> commonRemotes = new ArrayList<GitRemote>(iterator.next().getRemotes());
   while (iterator.hasNext()) {
     GitRepository repository = iterator.next();
     Collection<String> remoteNames = getRemoteNames(repository);
     for (Iterator<GitRemote> commonIter = commonRemotes.iterator(); commonIter.hasNext(); ) {
       GitRemote remote = commonIter.next();
       if (!remoteNames.contains(remote.getName())) {
         commonIter.remove();
       }
     }
   }
   return commonRemotes;
 }
  @Nullable
  public static String getGithubUrl(final GitRemote gitRemote) {
    final GithubSettings githubSettings = GithubSettings.getInstance();
    final String host = githubSettings.getHost();
    final String username = githubSettings.getLogin();

    // TODO this doesn't work with organizational accounts
    final String userRepoMarkerSSHProtocol = host + ":" + username + "/";
    final String userRepoMarkerOtherProtocols = host + "/" + username + "/";
    for (String pushUrl : gitRemote.getUrls()) {
      if (pushUrl.contains(userRepoMarkerSSHProtocol)
          || pushUrl.contains(userRepoMarkerOtherProtocols)) {
        return pushUrl;
      }
    }
    return null;
  }
  private ListenableFuture<Pair<String, GitCommandResult>> doPushCommits(
      @NotNull final GitRepository gitRepository,
      @NotNull final GitLocalBranch localBranch,
      @NotNull final GitRemote gitRemote,
      @NotNull final ProgressIndicator indicator) {
    // just set the result without going off to another thread, we should already be in a background
    // task
    SettableFuture<Pair<String, GitCommandResult>> pushResult =
        SettableFuture.<Pair<String, GitCommandResult>>create();

    indicator.setText(TfPluginBundle.message(TfPluginBundle.KEY_CREATE_PR_PUSH_TITLE));
    final Git git = ServiceManager.getService(Git.class);

    final GitRemoteBranch trackingBranch = localBranch.findTrackedBranch(gitRepository);

    final String createdBranchNameOnServer;
    final StringBuilder pushSpec = new StringBuilder(localBranch.getName());
    if (trackingBranch != null && trackingBranch.getRemote().equals(gitRemote)) {
      // if the tracking branch is on the same remote, we should update that
      pushSpec.append(":").append(trackingBranch.getNameForRemoteOperations());
      createdBranchNameOnServer = trackingBranch.getNameForRemoteOperations();
    } else {
      createdBranchNameOnServer = localBranch.getName();
    }

    final String fetchUrl = getFetchUrl(gitRemote);
    final String pushSpecStr = pushSpec.toString();
    final String gitRemoteName = gitRemote.getName();
    logger.debug("Pushing {} to {}: {}", pushSpecStr, gitRemoteName, fetchUrl);
    final GitCommandResult result =
        git.push(gitRepository, gitRemoteName, fetchUrl, pushSpecStr, true);

    if (result.success()) {
      pushResult.set(Pair.create(createdBranchNameOnServer, result));
    } else {
      final String errMsg = result.getErrorOutputAsJoinedString();
      pushResult.setException(new GitExecutionException(errMsg, null));
    }

    return pushResult;
  }
 private String getFetchUrl(@NotNull final GitRemote gitRemote) {
   return gitRemote.getFirstUrl();
 }