mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Rewrite Git fetch procedure for better API and cleaner code
GitFetcher appears to be not convenient to use, and has some serious flaws, but it is already used by several external plugins, so it is hard to rewrite it keeping the compatibility. Thus introducing a new API to fetch - the GitFetchSupport; GitFetcher is kept intact and deprecated.
This commit is contained in:
@@ -211,10 +211,10 @@
|
||||
<projectService serviceInterface="git4idea.branch.GitBrancher"
|
||||
serviceImplementation="git4idea.branch.GitBrancherImpl"/>
|
||||
<projectService serviceImplementation="git4idea.GitUserRegistry" />
|
||||
|
||||
<projectService serviceImplementation="git4idea.branch.DeepComparatorHolder"/>
|
||||
<projectService serviceInterface="git4idea.config.GitExecutableProblemsNotifier"
|
||||
serviceImplementation="git4idea.config.GitExecutableProblemsNotifier"/>
|
||||
<projectService serviceInterface="git4idea.fetch.GitFetchSupport" serviceImplementation="git4idea.fetch.GitFetchSupportImpl" />
|
||||
|
||||
<applicationService serviceInterface="git4idea.config.GitVcsApplicationSettings"
|
||||
serviceImplementation="git4idea.config.GitVcsApplicationSettings"/>
|
||||
|
||||
@@ -9,11 +9,13 @@ import git4idea.GitUtil;
|
||||
import git4idea.GitVcs;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import git4idea.update.GitFetcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static git4idea.GitUtil.getRepositoriesFromRoots;
|
||||
import static git4idea.fetch.GitFetchSupport.fetchSupport;
|
||||
|
||||
public class GitFetch extends GitRepositoryAction {
|
||||
@Override
|
||||
@NotNull
|
||||
@@ -29,8 +31,7 @@ public class GitFetch extends GitRepositoryAction {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
GitRepositoryManager repositoryManager = GitUtil.getRepositoryManager(project);
|
||||
new GitFetcher(project, indicator, true).fetchRootsAndNotify(GitUtil.getRepositoriesFromRoots(repositoryManager, gitRoots),
|
||||
null, true);
|
||||
fetchSupport(project).fetch(getRepositoriesFromRoots(repositoryManager, gitRoots)).showNotification();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.fetch;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface GitFetchResult {
|
||||
void showNotification();
|
||||
|
||||
boolean showNotificationIfFailed();
|
||||
|
||||
boolean showNotificationIfFailed(@NotNull String title);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.fetch;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* High-level API to execute the {@code git fetch} command.
|
||||
*/
|
||||
public interface GitFetchSupport {
|
||||
|
||||
/**
|
||||
* For each given repository, fetches the "default" remote.
|
||||
* The latter is identified by {@link #getDefaultRemoteToFetch}.
|
||||
*/
|
||||
@NotNull
|
||||
GitFetchResult fetch(@NotNull Collection<GitRepository> repositories);
|
||||
|
||||
/**
|
||||
* Fetches the given remote.
|
||||
*/
|
||||
@NotNull
|
||||
GitFetchResult fetch(@NotNull GitRepository repository, @NotNull GitRemote remote);
|
||||
|
||||
/**
|
||||
* Fetches all specified remotes in the repository.
|
||||
*/
|
||||
@NotNull
|
||||
GitFetchResult fetch(@NotNull GitRepository repository, @NotNull List<GitRemote> remotes);
|
||||
|
||||
/**
|
||||
* Returns the default remote to fetch from, or null if there are no remotes in the repository,
|
||||
* or if it is impossible to guess which remote is default.
|
||||
*/
|
||||
@Nullable
|
||||
GitRemote getDefaultRemoteToFetch(@NotNull GitRepository repository);
|
||||
|
||||
@NotNull
|
||||
static GitFetchSupport fetchSupport(@NotNull Project project) {
|
||||
return ServiceManager.getService(project, GitFetchSupport.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package git4idea.fetch
|
||||
|
||||
import com.intellij.dvcs.MultiMessage
|
||||
import com.intellij.dvcs.MultiRootMessage
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vcs.VcsNotifier
|
||||
import com.intellij.openapi.vcs.VcsNotifier.STANDARD_NOTIFICATION
|
||||
import git4idea.GitUtil.findRemoteByName
|
||||
import git4idea.GitUtil.mention
|
||||
import git4idea.commands.Git
|
||||
import git4idea.repo.GitRemote
|
||||
import git4idea.repo.GitRemote.ORIGIN
|
||||
import git4idea.repo.GitRepository
|
||||
import java.util.regex.Pattern
|
||||
|
||||
private val LOG = logger<GitFetchSupportImpl>()
|
||||
private val PRUNE_PATTERN = Pattern.compile("\\s*x\\s*\\[deleted\\].*->\\s*(\\S*)") // x [deleted] (none) -> origin/branch
|
||||
|
||||
internal class GitFetchSupportImpl(val project: Project) : GitFetchSupport {
|
||||
|
||||
override fun getDefaultRemoteToFetch(repository: GitRepository): GitRemote? {
|
||||
val remotes = repository.remotes
|
||||
return when {
|
||||
remotes.isEmpty() -> null
|
||||
remotes.size == 1 -> remotes.first()
|
||||
else -> {
|
||||
// this emulates behavior of the native `git fetch`:
|
||||
// if current branch doesn't give a hint, then return "origin"; if there is no "origin", don't guess and fail
|
||||
repository.currentBranch?.findTrackedBranch(repository)?.remote ?: findRemoteByName(repository, ORIGIN)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun fetch(repositories: Collection<GitRepository>): GitFetchResult {
|
||||
val results = mutableMapOf<GitRepository, RepoResult>()
|
||||
for (repository in repositories) {
|
||||
val remote = getDefaultRemoteToFetch(repository)
|
||||
if (remote != null) results[repository] = doFetch(repository, listOf(remote))
|
||||
else LOG.info("No remote to fetch found in $repository")
|
||||
}
|
||||
return resultOf(results)
|
||||
}
|
||||
|
||||
override fun fetch(repository: GitRepository, remote: GitRemote): GitFetchResult {
|
||||
return fetch(repository, listOf(remote))
|
||||
}
|
||||
|
||||
override fun fetch(repository: GitRepository, remotes: List<GitRemote>): GitFetchResult {
|
||||
return resultOf(mapOf(Pair(repository, doFetch(repository, remotes))))
|
||||
}
|
||||
|
||||
private fun doFetch(repository: GitRepository, remotes: List<GitRemote>): RepoResult {
|
||||
val results = mutableMapOf<GitRemote, SingleRemoteResult>()
|
||||
for (remote in remotes) {
|
||||
results[remote] = doFetch(repository, remote)
|
||||
}
|
||||
return RepoResult(results)
|
||||
}
|
||||
|
||||
private fun doFetch(repository: GitRepository, remote: GitRemote): SingleRemoteResult {
|
||||
val result = Git.getInstance().fetch(repository, remote, emptyList())
|
||||
val pruned = result.output.mapNotNull { getPrunedRef(it) }
|
||||
val error = if (result.success()) null else result.errorOutputAsJoinedString
|
||||
return SingleRemoteResult(error, pruned)
|
||||
}
|
||||
|
||||
private fun getPrunedRef(line: String): String? {
|
||||
val matcher = PRUNE_PATTERN.matcher(line)
|
||||
return if (matcher.matches()) matcher.group(1) else null
|
||||
}
|
||||
|
||||
private fun resultOf(results: Map<GitRepository, RepoResult>) = FetchResultImpl(project, results)
|
||||
|
||||
private class RepoResult(val results: Map<GitRemote, SingleRemoteResult>) {
|
||||
/*
|
||||
For simplicity, remote and repository results are merged separately.
|
||||
It means that they are not merged, if two repositories have two remotes,
|
||||
and then fetch succeeds for the first remote in both repos, and fails for the second remote in both repos.
|
||||
Such cases are rare, and can be handled when actual problem is reported.
|
||||
*/
|
||||
|
||||
fun totallySuccessful() = results.values.all { it.success() }
|
||||
|
||||
fun error(): String? {
|
||||
val errorMessage = multiRemoteMessage()
|
||||
for ((remote, result) in results) {
|
||||
if (result.error != null) errorMessage.append(remote, result.error)
|
||||
}
|
||||
return errorMessage.asString()
|
||||
}
|
||||
|
||||
fun prunedRefs(): String {
|
||||
val prunedRefs = multiRemoteMessage()
|
||||
for ((remote, result) in results) {
|
||||
if (result.prunedRefs.isNotEmpty()) prunedRefs.append(remote, result.prunedRefs.joinToString("\n"))
|
||||
}
|
||||
return prunedRefs.asString()
|
||||
}
|
||||
|
||||
private fun multiRemoteMessage() = MultiMessage(results.keys, GitRemote::getName, GitRemote::getName)
|
||||
}
|
||||
|
||||
private class SingleRemoteResult(val error: String?, val prunedRefs: List<String>) {
|
||||
fun success() = error == null
|
||||
}
|
||||
|
||||
private class FetchResultImpl(val project: Project,
|
||||
val results: Map<GitRepository, RepoResult>) : GitFetchResult {
|
||||
|
||||
override fun showNotification() {
|
||||
doShowNotification()
|
||||
}
|
||||
|
||||
override fun showNotificationIfFailed(): Boolean {
|
||||
return showNotificationIfFailed("Fetch Failed")
|
||||
}
|
||||
|
||||
override fun showNotificationIfFailed(title: String): Boolean {
|
||||
val failure = results.values.any { !it.totallySuccessful() }
|
||||
if (failure) doShowNotification(title)
|
||||
return !failure
|
||||
}
|
||||
|
||||
private fun doShowNotification(failureTitle: String = "Fetch Failed") {
|
||||
val roots = results.keys.map { it.root }
|
||||
val errorMessage = MultiRootMessage(project, roots, true)
|
||||
val prunedRefs = MultiRootMessage(project, roots, true)
|
||||
|
||||
val failed = results.filterValues { !it.totallySuccessful() }
|
||||
|
||||
for ((repo, result) in failed) {
|
||||
if (result.error() != null) errorMessage.append(repo.root, result.error()!!)
|
||||
}
|
||||
for ((repo, result) in results) {
|
||||
prunedRefs.append(repo.root, result.prunedRefs())
|
||||
}
|
||||
|
||||
val type = if (failed.isEmpty()) NotificationType.INFORMATION else NotificationType.ERROR
|
||||
val mentionFailedRepos = if (failed.size == roots.size) "" else mention(failed.keys)
|
||||
val title = if (failed.isEmpty()) "<b>Fetch Successful</b>" else "<b>$failureTitle</b>$mentionFailedRepos"
|
||||
val message = title + prefixWithBr(errorMessage.asString()) + prefixWithBr(prunedRefs.asString())
|
||||
val notification = STANDARD_NOTIFICATION.createNotification("", message, type, null)
|
||||
VcsNotifier.getInstance(project).notify(notification)
|
||||
}
|
||||
|
||||
private fun prefixWithBr(text: String): String = if (text.isNotEmpty()) "<br/>$text" else ""
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,9 @@ import static com.intellij.openapi.util.text.StringUtil.join;
|
||||
import static com.intellij.openapi.util.text.StringUtil.pluralize;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
* @deprecated Use {@link git4idea.fetch.GitFetchSupport}
|
||||
*/
|
||||
@Deprecated
|
||||
public final class GitFetchResult {
|
||||
|
||||
private final Type myType;
|
||||
|
||||
@@ -33,6 +33,7 @@ import git4idea.branch.GitBranchUtil;
|
||||
import git4idea.commands.Git;
|
||||
import git4idea.commands.GitCommandResult;
|
||||
import git4idea.commands.GitLineHandlerListener;
|
||||
import git4idea.fetch.GitFetchSupport;
|
||||
import git4idea.repo.GitBranchTrackInfo;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
@@ -51,6 +52,10 @@ import static git4idea.GitBranch.REFS_HEADS_PREFIX;
|
||||
import static git4idea.GitBranch.REFS_REMOTES_PREFIX;
|
||||
import static git4idea.commands.GitAuthenticationListener.GIT_AUTHENTICATION_SUCCESS;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link GitFetchSupport}
|
||||
*/
|
||||
@Deprecated
|
||||
public class GitFetcher {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GitFetcher.class);
|
||||
@@ -78,7 +83,9 @@ public class GitFetcher {
|
||||
/**
|
||||
* Invokes 'git fetch'.
|
||||
* @return true if fetch was successful, false in the case of error.
|
||||
* @deprecated Use {@link GitFetchSupport}
|
||||
*/
|
||||
@Deprecated
|
||||
public GitFetchResult fetch(@NotNull GitRepository repository) {
|
||||
// TODO need to have a fair compound result here
|
||||
GitFetchResult fetchResult = myFetchAll ? fetchAll(repository) : fetchCurrentRemote(repository);
|
||||
@@ -87,6 +94,10 @@ public class GitFetcher {
|
||||
return fetchResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link GitFetchSupport}
|
||||
*/
|
||||
@Deprecated
|
||||
@NotNull
|
||||
public GitFetchResult fetch(@NotNull VirtualFile root, @NotNull String remoteName, @Nullable String branch) {
|
||||
GitRepository repository = myRepositoryManager.getRepositoryForRoot(root);
|
||||
@@ -211,7 +222,7 @@ public class GitFetcher {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getFetchSpecForBranch(@NotNull String branch, @NotNull String remoteName) {
|
||||
private static String getFetchSpecForBranch(@NotNull String branch, @NotNull String remoteName) {
|
||||
branch = getRidOfPrefixIfExists(branch);
|
||||
return REFS_HEADS_PREFIX + branch + ":" + REFS_REMOTES_PREFIX + remoteName + "/" + branch;
|
||||
}
|
||||
@@ -254,7 +265,9 @@ public class GitFetcher {
|
||||
* Use this when fetch is a part of a compound process.
|
||||
* @param notifySuccess if set to {@code true} successful notification will be displayed.
|
||||
* @return true if all fetches were successful, false if at least one fetch failed.
|
||||
* @deprecated Use {@link GitFetchSupport}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean fetchRootsAndNotify(@NotNull Collection<GitRepository> roots,
|
||||
@Nullable String errorNotificationTitle, boolean notifySuccess) {
|
||||
MultiRootMessage additionalInfo = new MultiRootMessage(myProject, GitUtil.getRootsFromRepositories(roots), true);
|
||||
|
||||
@@ -44,6 +44,7 @@ import java.util.*;
|
||||
import static com.intellij.dvcs.DvcsUtil.getShortRepositoryName;
|
||||
import static git4idea.GitUtil.getRootsFromRepositories;
|
||||
import static git4idea.GitUtil.mention;
|
||||
import static git4idea.fetch.GitFetchSupport.fetchSupport;
|
||||
import static git4idea.util.GitUIUtil.*;
|
||||
|
||||
/**
|
||||
@@ -313,7 +314,7 @@ public class GitUpdateProcess {
|
||||
|
||||
// fetch all roots. If an error happens, return false and notify about errors.
|
||||
private boolean fetchAndNotify(@NotNull Collection<GitRepository> repositories) {
|
||||
return new GitFetcher(myProject, myProgressIndicator, false).fetchRootsAndNotify(repositories, "Update failed", false);
|
||||
return fetchSupport(myProject).fetch(repositories).showNotificationIfFailed("Update failed");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,10 @@ import com.intellij.dvcs.util.CommitCompareInfo;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.*;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.progress.util.BackgroundTaskUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
@@ -33,6 +36,7 @@ import com.intellij.vcs.log.VcsCommitMetadata;
|
||||
import git4idea.DialogManager;
|
||||
import git4idea.GitCommit;
|
||||
import git4idea.GitLocalBranch;
|
||||
import git4idea.GitUtil;
|
||||
import git4idea.changes.GitChangeUtils;
|
||||
import git4idea.commands.Git;
|
||||
import git4idea.commands.GitCommandResult;
|
||||
@@ -40,8 +44,6 @@ import git4idea.history.GitHistoryUtils;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
import git4idea.ui.branch.GitCompareBranchesHelper;
|
||||
import git4idea.update.GitFetchResult;
|
||||
import git4idea.update.GitFetcher;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.github.api.GithubApiRequestExecutor;
|
||||
@@ -67,6 +69,8 @@ import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import static git4idea.fetch.GitFetchSupport.fetchSupport;
|
||||
|
||||
public class GithubCreatePullRequestWorker {
|
||||
private static final Logger LOG = GithubUtil.LOG;
|
||||
private static final String CANNOT_CREATE_PULL_REQUEST = "Can't Create Pull Request";
|
||||
@@ -331,13 +335,13 @@ public class GithubCreatePullRequestWorker {
|
||||
}
|
||||
|
||||
private void doFetchRemote(@NotNull ForkInfo fork) {
|
||||
if (fork.getRemoteName() == null) return;
|
||||
|
||||
GitFetchResult result =
|
||||
new GitFetcher(myProject, new EmptyProgressIndicator(), false).fetch(myGitRepository.getRoot(), fork.getRemoteName(), null);
|
||||
if (!result.isSuccess()) {
|
||||
GitFetcher.displayFetchResult(myProject, result, null, result.getErrors());
|
||||
String remoteName = fork.getRemoteName();
|
||||
if (remoteName == null) return;
|
||||
GitRemote remote = GitUtil.findRemoteByName(myGitRepository, remoteName);
|
||||
if (remote == null) {
|
||||
LOG.warn("Couldn't find remote " + remoteName + " in " + myGitRepository);
|
||||
}
|
||||
fetchSupport(myProject).fetch(myGitRepository, remote).showNotificationIfFailed();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,8 +20,6 @@ import git4idea.rebase.GitRebaser;
|
||||
import git4idea.repo.GitRemote;
|
||||
import git4idea.repo.GitRepository;
|
||||
import git4idea.repo.GitRepositoryManager;
|
||||
import git4idea.update.GitFetchResult;
|
||||
import git4idea.update.GitFetcher;
|
||||
import git4idea.update.GitUpdateResult;
|
||||
import git4idea.util.GitPreservingProcess;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -39,6 +37,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static git4idea.commands.GitLocalChangesWouldBeOverwrittenDetector.Operation.CHECKOUT;
|
||||
import static git4idea.fetch.GitFetchSupport.fetchSupport;
|
||||
|
||||
public class GithubRebaseAction extends AbstractGithubUrlGroupingAction {
|
||||
private static final Logger LOG = GithubUtil.LOG;
|
||||
@@ -188,13 +187,13 @@ public class GithubRebaseAction extends AbstractGithubUrlGroupingAction {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean fetchParent(@NotNull ProgressIndicator indicator) {
|
||||
GitFetchResult result = new GitFetcher(myProject, indicator, false).fetch(myRepository.getRoot(), "upstream", null);
|
||||
if (!result.isSuccess()) {
|
||||
GitFetcher.displayFetchResult(myProject, result, null, result.getErrors());
|
||||
private boolean fetchParent(@NotNull final ProgressIndicator indicator) {
|
||||
GitRemote remote = GitUtil.findRemoteByName(myRepository, "upstream");
|
||||
if (remote == null) {
|
||||
LOG.warn("Couldn't find remote " + " remoteName " + " in " + myRepository);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return fetchSupport(myProject).fetch(myRepository, remote).showNotificationIfFailed();
|
||||
}
|
||||
|
||||
private void rebaseCurrentBranch(@NotNull ProgressIndicator indicator) {
|
||||
|
||||
Reference in New Issue
Block a user