mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[git] Detect remote protocol from the url
* Clone, fetch and ls-remote are trivial: just pass the url parameter.
* Pull: modify the method signature, since it can return pull or merge
handler depending on the situation. For merge url is not needed.
* Standard Push (GitPusher):
- simplify the logic by taking the first url
instead of iterating over all of them,
because we don't support pushing to several urls very well anyway.
- report error if there are no push urls: GitPusher shouldn't be
called in this case at all.
* Push when remote branch is deleted (GitDeleteRemoteBranchOperation):
same as for the standard push: take the first url,
report error if there are no urls defined for the remote.
This commit is contained in:
@@ -92,9 +92,9 @@ public class GitPull extends GitRepositoryAction {
|
||||
if (!fetchSuccessful) {
|
||||
return;
|
||||
}
|
||||
handlerReference.set(dialog.pullOrMergeHandler(false));
|
||||
handlerReference.set(dialog.pullOrMergeHandler(null));
|
||||
} else {
|
||||
handlerReference.set(dialog.pullOrMergeHandler(true));
|
||||
handlerReference.set(dialog.pullOrMergeHandler(url));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ import static com.intellij.openapi.util.text.StringUtil.pluralize;
|
||||
*/
|
||||
abstract class GitBranchOperation {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GitBranchOperation.class);
|
||||
protected static final Logger LOG = Logger.getInstance(GitBranchOperation.class);
|
||||
|
||||
@NotNull protected final Project myProject;
|
||||
@NotNull protected final GitPlatformFacade myFacade;
|
||||
|
||||
@@ -152,24 +152,31 @@ class GitDeleteRemoteBranchOperation extends GitBranchOperation {
|
||||
private GitCommandResult pushDeletion(@NotNull GitRepository repository, @NotNull String remoteName, @NotNull String branchName) {
|
||||
GitRemote remote = getRemoteByName(repository, remoteName);
|
||||
if (remote == null) {
|
||||
return pushDeletionNatively(repository, remoteName, branchName);
|
||||
String error = "Couldn't find remote by name: " + remoteName;
|
||||
LOG.error(error);
|
||||
return GitCommandResult.error(error);
|
||||
}
|
||||
|
||||
String remoteUrl = remote.getFirstUrl();
|
||||
if (remoteUrl != null && GitHttpAdapter.shouldUseJGit(remoteUrl)) {
|
||||
if (remoteUrl == null) {
|
||||
LOG.warn("No urls are defined for remote: " + remote);
|
||||
return GitCommandResult.error("There is no urls defined for remote " + remote.getName());
|
||||
}
|
||||
if (GitHttpAdapter.shouldUseJGit(remoteUrl)) {
|
||||
String fullBranchName = branchName.startsWith(GitBranch.REFS_HEADS_PREFIX) ? branchName : GitBranch.REFS_HEADS_PREFIX + branchName;
|
||||
String spec = ":" + fullBranchName;
|
||||
GitSimplePushResult simplePushResult = GitHttpAdapter.push(repository, remote.getName(), remoteUrl, spec);
|
||||
return convertSimplePushResultToCommandResult(simplePushResult);
|
||||
}
|
||||
else {
|
||||
return pushDeletionNatively(repository, remoteName, branchName);
|
||||
return pushDeletionNatively(repository, remoteName, remoteUrl, branchName);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private GitCommandResult pushDeletionNatively(@NotNull GitRepository repository, @NotNull String remoteName, @NotNull String branchName) {
|
||||
return myGit.push(repository, remoteName, ":" + branchName);
|
||||
private GitCommandResult pushDeletionNatively(@NotNull GitRepository repository, @NotNull String remoteName, @NotNull String url,
|
||||
@NotNull String branchName) {
|
||||
return myGit.push(repository, remoteName, url,":" + branchName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -164,7 +164,7 @@ public class GitCloneDialog extends DialogWrapper {
|
||||
*/
|
||||
private boolean test(String url) {
|
||||
final GitLineHandlerPasswordRequestAware handler = new GitLineHandlerPasswordRequestAware(myProject, new File("."), GitCommand.LS_REMOTE);
|
||||
handler.setRemoteProtocol(GitRemoteProtocol.SSH);
|
||||
handler.setRemoteProtocol(url);
|
||||
handler.addParameters(url, "master");
|
||||
GitTask task = new GitTask(myProject, handler, GitBundle.message("clone.testing", url));
|
||||
GitTaskResult result = task.executeModal();
|
||||
|
||||
@@ -92,11 +92,11 @@ public interface Git {
|
||||
GitCommandResult tip(@NotNull GitRepository repository, @NotNull String branchName);
|
||||
|
||||
@NotNull
|
||||
GitCommandResult push(@NotNull GitRepository repository, @NotNull String remote, @NotNull String spec,
|
||||
GitCommandResult push(@NotNull GitRepository repository, @NotNull String remote, @NotNull String url, @NotNull String spec,
|
||||
@NotNull GitLineHandlerListener... listeners);
|
||||
|
||||
@NotNull
|
||||
GitCommandResult push(@NotNull GitRepository repository, @NotNull GitPushSpec pushSpec,
|
||||
GitCommandResult push(@NotNull GitRepository repository, @NotNull GitPushSpec spec, @NotNull String url,
|
||||
@NotNull GitLineHandlerListener... listeners);
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -80,4 +81,8 @@ public class GitCommandResult {
|
||||
return myException;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static GitCommandResult error(@NotNull String error) {
|
||||
return new GitCommandResult(false, 1, Collections.singletonList(error), Collections.<String>emptyList(), null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,8 +217,8 @@ public abstract class GitHandler {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setRemoteProtocol(@NotNull GitRemoteProtocol remoteProtocol) {
|
||||
myRemoteProtocol = remoteProtocol;
|
||||
public void setRemoteProtocol(@NotNull String url) {
|
||||
myRemoteProtocol = GitRemoteProtocol.fromUrl(url);
|
||||
}
|
||||
|
||||
protected boolean isRemote() {
|
||||
|
||||
@@ -132,7 +132,7 @@ public class GitImpl implements Git {
|
||||
public GitCommandResult clone(@NotNull Project project, @NotNull File parentDirectory, @NotNull String url,
|
||||
@NotNull String clonedDirectoryName, @NotNull GitLineHandlerListener... listeners) {
|
||||
GitLineHandlerPasswordRequestAware handler = new GitLineHandlerPasswordRequestAware(project, parentDirectory, GitCommand.CLONE);
|
||||
handler.setRemoteProtocol(GitRemoteProtocol.SSH);
|
||||
handler.setRemoteProtocol(url);
|
||||
handler.addParameters("--progress");
|
||||
handler.addParameters(url);
|
||||
handler.addParameters(clonedDirectoryName);
|
||||
@@ -356,11 +356,11 @@ public class GitImpl implements Git {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public GitCommandResult push(@NotNull GitRepository repository, @NotNull String remote, @NotNull String spec,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
public GitCommandResult push(@NotNull GitRepository repository, @NotNull String remote, @NotNull String url, @NotNull String spec,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(repository.getProject(), repository.getRoot(),
|
||||
GitCommand.PUSH);
|
||||
h.setRemoteProtocol(GitRemoteProtocol.SSH);
|
||||
h.setRemoteProtocol(url);
|
||||
h.setSilent(false);
|
||||
addListeners(h, listeners);
|
||||
h.addProgressParameter();
|
||||
@@ -371,12 +371,12 @@ public class GitImpl implements Git {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public GitCommandResult push(@NotNull GitRepository repository, @NotNull GitPushSpec pushSpec,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
public GitCommandResult push(@NotNull GitRepository repository, @NotNull GitPushSpec pushSpec, @NotNull String url,
|
||||
@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);
|
||||
return push(repository, remote.getName(), url, pushSpec.getSource().getName() + ":" + destination, listeners);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -15,11 +15,26 @@
|
||||
*/
|
||||
package git4idea.commands;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
public enum GitRemoteProtocol {
|
||||
GIT,
|
||||
SSH,
|
||||
HTTP
|
||||
HTTP;
|
||||
|
||||
@NotNull
|
||||
public static GitRemoteProtocol fromUrl(@NotNull String url) {
|
||||
url = url.toLowerCase();
|
||||
if (url.startsWith("http")) {
|
||||
return HTTP;
|
||||
}
|
||||
if (url.startsWith("git://")) { // "://" are there not to mix with scp-like syntax used for SSH: git@host.com/path/to.git
|
||||
return GIT;
|
||||
}
|
||||
return SSH;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import git4idea.GitRemoteBranch;
|
||||
import git4idea.GitUtil;
|
||||
import git4idea.commands.GitCommand;
|
||||
import git4idea.commands.GitLineHandler;
|
||||
import git4idea.commands.GitRemoteProtocol;
|
||||
import git4idea.i18n.GitBundle;
|
||||
import git4idea.repo.GitBranchTrackInfo;
|
||||
import git4idea.repo.GitRemote;
|
||||
@@ -154,12 +153,13 @@ public class GitPullDialog extends DialogWrapper {
|
||||
/**
|
||||
* @return a pull handler configured according to dialog options
|
||||
*/
|
||||
public GitLineHandler pullOrMergeHandler(boolean pull) {
|
||||
public GitLineHandler pullOrMergeHandler(@Nullable String url) {
|
||||
boolean pull = url != null;
|
||||
GitLineHandler h = new GitLineHandler(myProject, gitRoot(), pull ? GitCommand.PULL : GitCommand.MERGE);
|
||||
// ignore merge failure for the pull
|
||||
h.ignoreErrorCode(1);
|
||||
if (pull) {
|
||||
h.setRemoteProtocol(GitRemoteProtocol.SSH);
|
||||
h.setRemoteProtocol(url);
|
||||
h.addProgressParameter();
|
||||
}
|
||||
h.addParameters("--no-stat");
|
||||
|
||||
@@ -318,21 +318,18 @@ public final class GitPusher {
|
||||
}
|
||||
|
||||
GitRemote remote = pushSpec.getRemote();
|
||||
String httpUrl = null;
|
||||
for (String pushUrl : remote.getPushUrls()) {
|
||||
if (GitHttpAdapter.shouldUseJGit(pushUrl)) {
|
||||
httpUrl = pushUrl;
|
||||
break; // TODO support http and ssh urls in one origin
|
||||
}
|
||||
Collection<String> pushUrls = remote.getPushUrls();
|
||||
if (pushUrls.isEmpty()) {
|
||||
LOG.error("No urls or pushUrls are defined for " + remote);
|
||||
return GitSimplePushResult.error("There are no URLs defined for remote " + remote.getName());
|
||||
}
|
||||
|
||||
String url = pushUrls.iterator().next();
|
||||
GitSimplePushResult pushResult;
|
||||
boolean pushOverHttp = httpUrl != null;
|
||||
if (pushOverHttp) {
|
||||
pushResult = GitHttpAdapter.push(repository, remote.getName(), httpUrl, formPushSpec(pushSpec, remote));
|
||||
if (GitHttpAdapter.shouldUseJGit(url)) {
|
||||
pushResult = GitHttpAdapter.push(repository, remote.getName(), url, formPushSpec(pushSpec, remote));
|
||||
}
|
||||
else {
|
||||
pushResult = pushNatively(repository, pushSpec);
|
||||
pushResult = pushNatively(repository, pushSpec, url);
|
||||
}
|
||||
|
||||
if (pushResult.getType() == GitSimplePushResult.Type.SUCCESS) {
|
||||
@@ -396,10 +393,10 @@ public final class GitPusher {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private GitSimplePushResult pushNatively(GitRepository repository, GitPushSpec pushSpec) {
|
||||
private GitSimplePushResult pushNatively(GitRepository repository, GitPushSpec pushSpec, @NotNull String url) {
|
||||
GitPushRejectedDetector rejectedDetector = new GitPushRejectedDetector();
|
||||
GitLineHandlerListener progressListener = GitStandardProgressAnalyzer.createListener(myProgressIndicator);
|
||||
GitCommandResult res = myGit.push(repository, pushSpec, rejectedDetector, progressListener);
|
||||
GitCommandResult res = myGit.push(repository, pushSpec, url, rejectedDetector, progressListener);
|
||||
if (rejectedDetector.rejected()) {
|
||||
Collection<String> rejectedBranches = rejectedDetector.getRejectedBranches();
|
||||
return GitSimplePushResult.reject(rejectedBranches);
|
||||
|
||||
@@ -132,7 +132,7 @@ public class GitFetcher {
|
||||
if (GitHttpAdapter.shouldUseJGit(url)) {
|
||||
return GitHttpAdapter.fetch(repository, remote, url, null);
|
||||
}
|
||||
return fetchNatively(repository.getRoot(), remote, null);
|
||||
return fetchNatively(repository.getRoot(), remote, url, null);
|
||||
}
|
||||
|
||||
// leaving this unused method, because the wanted behavior can change again
|
||||
@@ -150,7 +150,7 @@ public class GitFetcher {
|
||||
if (GitHttpAdapter.shouldUseJGit(url)) {
|
||||
return GitHttpAdapter.fetch(repository, remote, url, remoteBranch);
|
||||
}
|
||||
return fetchNatively(repository.getRoot(), remote, remoteBranch);
|
||||
return fetchNatively(repository.getRoot(), remote, url, remoteBranch);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -198,7 +198,7 @@ public class GitFetcher {
|
||||
}
|
||||
}
|
||||
else {
|
||||
GitFetchResult res = fetchNatively(repository.getRoot(), remote, null);
|
||||
GitFetchResult res = fetchNatively(repository.getRoot(), remote, url, null);
|
||||
res.addPruneInfo(fetchResult.getPrunedRefs());
|
||||
fetchResult = res;
|
||||
if (!fetchResult.isSuccess()) {
|
||||
@@ -209,9 +209,9 @@ public class GitFetcher {
|
||||
return fetchResult;
|
||||
}
|
||||
|
||||
private GitFetchResult fetchNatively(@NotNull VirtualFile root, @NotNull GitRemote remote, @Nullable String branch) {
|
||||
private GitFetchResult fetchNatively(@NotNull VirtualFile root, @NotNull GitRemote remote, @NotNull String url, @Nullable String branch) {
|
||||
final GitLineHandlerPasswordRequestAware h = new GitLineHandlerPasswordRequestAware(myProject, root, GitCommand.FETCH);
|
||||
h.setRemoteProtocol(GitRemoteProtocol.SSH);
|
||||
h.setRemoteProtocol(url);
|
||||
h.addProgressParameter();
|
||||
if (GitVersionSpecialty.SUPPORTS_FETCH_PRUNE.existsIn(myVcs.getVersion())) {
|
||||
h.addParameters("--prune");
|
||||
|
||||
@@ -190,9 +190,7 @@ public class GitTestImpl implements Git {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GitCommandResult push(@NotNull GitRepository repository,
|
||||
@NotNull String remote,
|
||||
@NotNull String spec,
|
||||
public GitCommandResult push(@NotNull GitRepository repository, @NotNull String remote, @NotNull String url, @NotNull String spec,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
@@ -200,8 +198,7 @@ public class GitTestImpl implements Git {
|
||||
@NotNull
|
||||
@Override
|
||||
public GitCommandResult push(@NotNull GitRepository repository,
|
||||
@NotNull GitPushSpec pushSpec,
|
||||
@NotNull GitLineHandlerListener... listeners) {
|
||||
@NotNull GitPushSpec spec, @NotNull String url, @NotNull GitLineHandlerListener... listeners) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user