@Nullable
  public GithubTargetInfo setTarget(@NotNull final GithubFullPath forkPath) {
    try {
      GithubInfo info =
          GithubUtil.computeValueInModal(
              myProject,
              "Access to GitHub",
              new ThrowableConvertor<ProgressIndicator, GithubInfo, IOException>() {
                @Override
                public GithubInfo convert(ProgressIndicator indicator) throws IOException {
                  // configure remote
                  GitRemote targetRemote = GithubUtil.findGithubRemote(myGitRepository, forkPath);
                  String targetRemoteName = targetRemote == null ? null : targetRemote.getName();
                  if (targetRemoteName == null) {
                    final AtomicReference<Integer> responseRef = new AtomicReference<Integer>();
                    ApplicationManager.getApplication()
                        .invokeAndWait(
                            new Runnable() {
                              @Override
                              public void run() {
                                responseRef.set(
                                    GithubNotifications.showYesNoDialog(
                                        myProject,
                                        "Can't Find Remote",
                                        "Configure remote for '" + forkPath.getUser() + "'?"));
                              }
                            },
                            indicator.getModalityState());
                    if (responseRef.get() == Messages.YES) {
                      targetRemoteName = configureRemote(myProject, myGitRepository, forkPath);
                    }
                  }

                  // load available branches
                  List<String> branches =
                      ContainerUtil.map(
                          GithubApiUtil.getRepoBranches(
                              myAuth, forkPath.getUser(), forkPath.getRepository()),
                          new Function<GithubBranch, String>() {
                            @Override
                            public String fun(GithubBranch githubBranch) {
                              return githubBranch.getName();
                            }
                          });

                  // fetch
                  if (targetRemoteName != null) {
                    GitFetchResult result =
                        new GitFetcher(myProject, indicator, false)
                            .fetch(myGitRepository.getRoot(), targetRemoteName, null);
                    if (!result.isSuccess()) {
                      GitFetcher.displayFetchResult(myProject, result, null, result.getErrors());
                      targetRemoteName = null;
                    }
                  }

                  return new GithubInfo(branches, targetRemoteName);
                }
              });

      myForkPath = forkPath;
      myTargetRemote = info.getTargetRemote();

      myDiffInfos.clear();
      if (canShowDiff()) {
        for (final String branch : info.getBranches()) {
          myDiffInfos.put(
              branch,
              new FutureTask<DiffInfo>(
                  new Callable<DiffInfo>() {
                    @Override
                    public DiffInfo call() throws Exception {
                      return loadDiffInfo(
                          myProject,
                          myGitRepository,
                          myCurrentBranch,
                          myTargetRemote + "/" + branch);
                    }
                  }));
        }
      }

      return new GithubTargetInfo(info.getBranches());
    } catch (GithubAuthenticationCanceledException e) {
      return null;
    } catch (IOException e) {
      GithubNotifications.showErrorDialog(myProject, CANNOT_CREATE_PULL_REQUEST, e);
      return null;
    }
  }
  public static void shareProjectOnGithub(
      @NotNull final Project project, @Nullable final VirtualFile file) {
    BasicAction.saveAll();

    // get gitRepository
    final GitRepository gitRepository = GithubUtil.getGitRepository(project, file);
    final boolean gitDetected = gitRepository != null;
    final VirtualFile root = gitDetected ? gitRepository.getRoot() : project.getBaseDir();

    // check for existing git repo
    boolean externalRemoteDetected = false;
    if (gitDetected) {
      final String githubRemote = GithubUtil.findGithubRemoteUrl(gitRepository);
      if (githubRemote != null) {
        GithubNotifications.showInfoURL(
            project, "Project is already on GitHub", "GitHub", githubRemote);
        return;
      }
      externalRemoteDetected = !gitRepository.getRemotes().isEmpty();
    }

    final GithubAuthDataHolder authHolder = GithubAuthDataHolder.createFromSettings();

    // get available GitHub repos with modal progress
    final GithubInfo githubInfo = loadGithubInfoWithModal(authHolder, project);
    if (githubInfo == null) {
      return;
    }

    // Show dialog (window)
    final GithubShareDialog shareDialog =
        new GithubShareDialog(
            project, githubInfo.getRepositoryNames(), githubInfo.getUser().canCreatePrivateRepo());
    DialogManager.show(shareDialog);
    if (!shareDialog.isOK()) {
      return;
    }
    final boolean isPrivate = shareDialog.isPrivate();
    final String name = shareDialog.getRepositoryName();
    final String description = shareDialog.getDescription();

    // finish the job in background
    final boolean finalExternalRemoteDetected = externalRemoteDetected;
    new Task.Backgroundable(project, "Sharing project on GitHub...") {
      @Override
      public void run(@NotNull ProgressIndicator indicator) {
        // create GitHub repo (network)
        LOG.info("Creating GitHub repository");
        indicator.setText("Creating GitHub repository...");
        final String url =
            createGithubRepository(project, authHolder, indicator, name, description, isPrivate);
        if (url == null) {
          return;
        }
        LOG.info("Successfully created GitHub repository");

        // creating empty git repo if git is not initialized
        LOG.info("Binding local project with GitHub");
        if (!gitDetected) {
          LOG.info("No git detected, creating empty git repo");
          indicator.setText("Creating empty git repo...");
          if (!createEmptyGitRepository(project, root, indicator)) {
            return;
          }
        }

        GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project);
        final GitRepository repository = repositoryManager.getRepositoryForRoot(root);
        LOG.assertTrue(repository != null, "GitRepository is null for root " + root);
        if (repository == null) {
          GithubNotifications.showError(
              project, "Failed to create GitHub Repository", "Can't find Git repository");
          return;
        }

        final String remoteUrl = GithubUrlUtil.getCloneUrl(githubInfo.getUser().getLogin(), name);
        final String remoteName = finalExternalRemoteDetected ? "github" : "origin";

        // git remote add origin [email protected]:login/name.git
        LOG.info("Adding GitHub as a remote host");
        indicator.setText("Adding GitHub as a remote host...");
        if (!GithubUtil.addGithubRemote(project, repository, remoteName, remoteUrl)) {
          return;
        }

        // create sample commit for binding project
        if (!performFirstCommitIfRequired(project, root, repository, indicator, name, url)) {
          return;
        }

        // git push origin master
        LOG.info("Pushing to github master");
        indicator.setText("Pushing to github master...");
        if (!pushCurrentBranch(project, repository, remoteName, remoteUrl, name, url)) {
          return;
        }

        GithubNotifications.showInfoURL(
            project, "Successfully shared project on GitHub", name, url);
      }
    }.queue();
  }