/**
   * This method calculates the commits and diff information against the tip of current branch and
   * the common ancestor of source branch (current branch) and target branch (selected remote
   * branch).
   *
   * <p>If there is no common parent (two branches are parallel), return an empty
   * GitCommitCompareInfo
   *
   * <p>This is potentially an expensive calculation, probably should do it on a background thread.
   * We will also attempt to cache the result
   *
   * <p>default access for testing so we bypass UI code, TODO: reevaluate the testing to properly
   * shutoff the access level
   *
   * @return gitChangesContainer on what has changed on source branch
   */
  GitChangesContainer getMyChangesCompareInfo() throws VcsException {

    final GitBranch currBranch = this.getSourceBranch();

    final GitRemoteBranch selectedRemoteBranch = this.getTargetBranch();

    // if source branch or currentBranch isn't set, just return empty diff
    if (selectedRemoteBranch == null || currBranch == null) {
      return GitChangesContainer.createChangesContainer(
          null,
          null,
          null,
          null,
          getDiffCompareInfoProvider().getEmptyDiff(this.gitRepository),
          this.gitRepository);
    }

    final String remoteBranchHash = selectedRemoteBranch.getHash().asString();
    final String currBranchHash = currBranch.getHash().asString();

    try {
      GitCommitCompareInfo changes =
          this.diffCache.get(new Pair<String, String>(currBranchHash, remoteBranchHash));

      return GitChangesContainer.createChangesContainer(
          currBranch.getName(),
          selectedRemoteBranch.getName(),
          currBranchHash,
          remoteBranchHash,
          changes,
          this.gitRepository);
    } catch (ExecutionException e) {
      throw new VcsException(e.getCause());
    }
  }
 @NotNull
 private Set<VcsRef> readBranches(@NotNull GitRepository repository) {
   StopWatch sw = StopWatch.start("readBranches in " + repository.getRoot().getName());
   VirtualFile root = repository.getRoot();
   repository.update();
   Collection<GitLocalBranch> localBranches = repository.getBranches().getLocalBranches();
   Collection<GitRemoteBranch> remoteBranches = repository.getBranches().getRemoteBranches();
   Set<VcsRef> refs = new THashSet<VcsRef>(localBranches.size() + remoteBranches.size());
   for (GitLocalBranch localBranch : localBranches) {
     refs.add(
         myVcsObjectsFactory.createRef(
             localBranch.getHash(), localBranch.getName(), GitRefManager.LOCAL_BRANCH, root));
   }
   for (GitRemoteBranch remoteBranch : remoteBranches) {
     refs.add(
         myVcsObjectsFactory.createRef(
             remoteBranch.getHash(),
             remoteBranch.getNameForLocalOperations(),
             GitRefManager.REMOTE_BRANCH,
             root));
   }
   String currentRevision = repository.getCurrentRevision();
   if (currentRevision != null) { // null => fresh repository
     refs.add(
         myVcsObjectsFactory.createRef(
             HashImpl.build(currentRevision), "HEAD", GitRefManager.HEAD, root));
   }
   sw.report();
   return refs;
 }
  @NotNull
  @Override
  public Collection<VcsRef> readAllRefs(@NotNull VirtualFile root) throws VcsException {
    if (!isRepositoryReady(root)) {
      return Collections.emptyList();
    }

    GitRepository repository = getRepository(root);
    repository.update();
    Collection<GitLocalBranch> localBranches = repository.getBranches().getLocalBranches();
    Collection<GitRemoteBranch> remoteBranches = repository.getBranches().getRemoteBranches();
    Collection<VcsRef> refs = new ArrayList<VcsRef>(localBranches.size() + remoteBranches.size());
    for (GitLocalBranch localBranch : localBranches) {
      refs.add(
          myVcsObjectsFactory.createRef(
              HashImpl.build(localBranch.getHash()),
              localBranch.getName(),
              GitRefManager.LOCAL_BRANCH,
              root));
    }
    for (GitRemoteBranch remoteBranch : remoteBranches) {
      refs.add(
          myVcsObjectsFactory.createRef(
              HashImpl.build(remoteBranch.getHash()),
              remoteBranch.getNameForLocalOperations(),
              GitRefManager.REMOTE_BRANCH,
              root));
    }
    String currentRevision = repository.getCurrentRevision();
    if (currentRevision != null) { // null => fresh repository
      refs.add(
          myVcsObjectsFactory.createRef(
              HashImpl.build(currentRevision), "HEAD", GitRefManager.HEAD, root));
    }

    refs.addAll(readTags(root));
    return refs;
  }