@NotNull private static GitUpdater getDefaultUpdaterForBranch( @NotNull Project project, @NotNull Git git, @NotNull VirtualFile root, @NotNull Map<VirtualFile, GitBranchPair> trackedBranches, @NotNull ProgressIndicator progressIndicator, @NotNull UpdatedFiles updatedFiles) { try { GitLocalBranch branch = GitBranchUtil.getCurrentBranch(project, root); boolean rebase = false; if (branch != null) { String rebaseValue = GitConfigUtil.getValue(project, root, "branch." + branch.getName() + ".rebase"); rebase = rebaseValue != null && rebaseValue.equalsIgnoreCase("true"); } if (rebase) { return new GitRebaseUpdater( project, git, root, trackedBranches, progressIndicator, updatedFiles); } } catch (VcsException e) { LOG.info("getDefaultUpdaterForBranch branch", e); } return new GitMergeUpdater( project, git, root, trackedBranches, progressIndicator, updatedFiles); }
@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; }
private static boolean pushCurrentBranch( @NotNull Project project, @NotNull GitRepository repository, @NotNull String remoteName, @NotNull String remoteUrl, @NotNull String name, @NotNull String url) { Git git = ServiceManager.getService(Git.class); GitLocalBranch currentBranch = repository.getCurrentBranch(); if (currentBranch == null) { GithubNotifications.showErrorURL( project, "Can't finish GitHub sharing process", "Successfully created project ", "'" + name + "'", " on GitHub, but initial push failed: no current branch", url); return false; } GitCommandResult result = git.push(repository, remoteName, remoteUrl, currentBranch.getName(), true); if (!result.success()) { GithubNotifications.showErrorURL( project, "Can't finish GitHub sharing process", "Successfully created project ", "'" + name + "'", " on GitHub, but initial push failed:<br/>" + result.getErrorOutputAsHtmlString(), url); return false; } return true; }
@Nullable private GitRemoteBranch getRemoteTrackingBranch() { final GitLocalBranch localBranch = this.getSourceBranch(); return localBranch != null && this.gitRepository != null ? localBranch.findTrackedBranch(this.gitRepository) : null; }
@Nullable public static GithubCreatePullRequestWorker createPullRequestWorker( @NotNull final Project project, @Nullable final VirtualFile file) { Git git = ServiceManager.getService(Git.class); GitRepository gitRepository = GithubUtil.getGitRepository(project, file); if (gitRepository == null) { GithubNotifications.showError( project, CANNOT_CREATE_PULL_REQUEST, "Can't find git repository"); return null; } gitRepository.update(); Pair<GitRemote, String> remote = GithubUtil.findGithubRemote(gitRepository); if (remote == null) { GithubNotifications.showError( project, CANNOT_CREATE_PULL_REQUEST, "Can't find GitHub remote"); return null; } String remoteName = remote.getFirst().getName(); String remoteUrl = remote.getSecond(); GithubFullPath path = GithubUrlUtil.getUserAndRepositoryFromRemoteUrl(remoteUrl); if (path == null) { GithubNotifications.showError( project, CANNOT_CREATE_PULL_REQUEST, "Can't process remote: " + remoteUrl); return null; } GitLocalBranch currentBranch = gitRepository.getCurrentBranch(); if (currentBranch == null) { GithubNotifications.showError(project, CANNOT_CREATE_PULL_REQUEST, "No current branch"); return null; } GithubAuthData auth; try { auth = GithubUtil.computeValueInModal( project, "Access to GitHub", new ThrowableConvertor<ProgressIndicator, GithubAuthData, IOException>() { @Override public GithubAuthData convert(ProgressIndicator indicator) throws IOException { return GithubUtil.getValidAuthDataFromConfig(project, indicator); } }); } catch (GithubAuthenticationCanceledException e) { return null; } catch (IOException e) { GithubNotifications.showError(project, CANNOT_CREATE_PULL_REQUEST, e); return null; } return new GithubCreatePullRequestWorker( project, git, gitRepository, path, remoteName, remoteUrl, currentBranch.getName(), auth); }
/** * For each root check that the repository is on branch, and this branch is tracking a remote * branch, and the remote branch exists. If it is not true for at least one of roots, notify and * return false. If branch configuration is OK for all roots, return true. */ private boolean checkTrackedBranchesConfigured() { LOG.info("checking tracked branch configuration..."); for (GitRepository repository : myRepositories) { VirtualFile root = repository.getRoot(); final GitLocalBranch branch = repository.getCurrentBranch(); if (branch == null) { LOG.info("checkTrackedBranchesConfigured: current branch is null in " + repository); notifyImportantError( myProject, "Can't update: no current branch", "You are in 'detached HEAD' state, which means that you're not on any branch" + rootStringIfNeeded(root) + "Checkout a branch to make update possible."); return false; } GitBranchTrackInfo trackInfo = GitBranchUtil.getTrackInfoForBranch(repository, branch); if (trackInfo == null) { final String branchName = branch.getName(); LOG.info( String.format( "checkTrackedBranchesConfigured: no track info for current branch %s in %s", branch, repository)); String recommendedCommand = String.format( GitVersionSpecialty.KNOWS_SET_UPSTREAM_TO.existsIn(repository.getVcs().getVersion()) ? "git branch --set-upstream-to origin/%1$s %1$s" : "git branch --set-upstream %1$s origin/%1$s", branchName); notifyImportantError( myProject, "Can't update: no tracked branch", "No tracked branch configured for branch " + code(branchName) + rootStringIfNeeded(root) + "To make your branch track a remote branch call, for example,<br/>" + "<code>" + recommendedCommand + "</code>"); return false; } myTrackedBranches.put(root, new GitBranchPair(branch, trackInfo.getRemoteBranch())); } return true; }
/* if user has changed the dropdown while we calculate the diff, this diff is out of date */ private boolean isChangesUpToDate(final GitChangesContainer changesContainer) { // target branches must match final GitRemoteBranch targetBranch = this.getTargetBranch(); if (changesContainer.getTargetBranchName() != null && targetBranch != null) { if (!changesContainer.getTargetBranchName().equals(targetBranch.getName())) { return false; } } // source branches must match final GitLocalBranch sourceBranch = this.getSourceBranch(); if (changesContainer.getSourceBranchName() != null && sourceBranch != null) { if (!changesContainer.getSourceBranchName().equals(sourceBranch.getName())) { return false; } } return true; }
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; }
@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; }