mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SVN 1.7: command line client - to be used for update (not switch) + http protocol
This commit is contained in:
@@ -26,9 +26,15 @@ public class ProxySvnAuthentication {
|
||||
private ProxySvnAuthentication() {
|
||||
}
|
||||
|
||||
public static SVNAuthentication proxy(final SVNAuthentication in, final boolean storeAuth) {
|
||||
if (in.isStorageAllowed() == storeAuth || (! in.isStorageAllowed())) return in;
|
||||
public static SVNAuthentication proxy(final SVNAuthentication in, final boolean storeAuth, boolean forceSaving) {
|
||||
if (forceSaving && storeAuth) {
|
||||
return putPassedValueAsSave(in, forceSaving);
|
||||
}
|
||||
if (in.isStorageAllowed() == storeAuth || ( ! in.isStorageAllowed())) return in;
|
||||
return putPassedValueAsSave(in, storeAuth);
|
||||
}
|
||||
|
||||
private static SVNAuthentication putPassedValueAsSave(SVNAuthentication in, boolean storeAuth) {
|
||||
final String userName = in.getUserName();
|
||||
if (in instanceof SVNPasswordAuthentication) {
|
||||
return new SVNPasswordAuthentication(userName, ((SVNPasswordAuthentication)in).getPassword(),
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.idea.svn17;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -67,6 +68,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
private IdeaSVNHostOptionsProvider myLocalHostOptionsProvider;
|
||||
private final ThreadLocalSavePermissions mySavePermissions;
|
||||
private final Map<Thread, String> myKeyAlgorithm;
|
||||
private boolean myArtificialSaving;
|
||||
|
||||
public SvnAuthenticationManager(final Project project, final File configDirectory) {
|
||||
super(configDirectory, true, null, null);
|
||||
@@ -82,6 +84,10 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
myInteraction = new MySvnAuthenticationInteraction(myProject);
|
||||
}
|
||||
|
||||
public void setArtificialSaving(boolean artificialSaving) {
|
||||
myArtificialSaving = artificialSaving;
|
||||
}
|
||||
|
||||
private void ensureListenerCreated() {
|
||||
if (myListener == null) {
|
||||
myListener = EventDispatcher.create(SvnAuthenticationListener.class);
|
||||
@@ -115,6 +121,11 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
myListener.getMulticaster().saveAttemptFinished(type, url, realm, kind);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) {
|
||||
myListener.getMulticaster().acknowledge(accepted, kind, realm, message, authentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requested(ProviderType type, SVNURL url, String realm, String kind, boolean canceled) {
|
||||
if (ProviderType.interactive.equals(type) && (! canceled)) {
|
||||
@@ -137,12 +148,18 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
String realm,
|
||||
SVNErrorMessage errorMessage,
|
||||
SVNAuthentication authentication) throws SVNException {
|
||||
boolean successSaving = false;
|
||||
myListener.getMulticaster().acknowledge(accepted, kind, realm, errorMessage, authentication);
|
||||
try {
|
||||
final boolean authStorageEnabled = getHostOptionsProvider().getHostOptions(authentication.getURL()).isAuthStorageEnabled();
|
||||
final SVNAuthentication proxy = ProxySvnAuthentication.proxy(authentication, authStorageEnabled);
|
||||
final SVNAuthentication proxy = ProxySvnAuthentication.proxy(authentication, authStorageEnabled, myArtificialSaving);
|
||||
super.acknowledgeAuthentication(accepted, kind, realm, errorMessage, proxy);
|
||||
successSaving = true;
|
||||
} finally {
|
||||
mySavePermissions.remove();
|
||||
if (myArtificialSaving) {
|
||||
throw new CredentialsSavedException(successSaving);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,11 +246,10 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
public void saveAuthentication(final SVNAuthentication auth, final String kind, final String realm) throws SVNException {
|
||||
final Boolean fromInteractive = ourJustEntered.get();
|
||||
ourJustEntered.set(null);
|
||||
if (! Boolean.TRUE.equals(fromInteractive)) {
|
||||
if (! myArtificialSaving && ! Boolean.TRUE.equals(fromInteractive)) {
|
||||
// not what user entered
|
||||
return;
|
||||
}
|
||||
|
||||
myListener.getMulticaster().saveAttemptStarted(ProviderType.persistent, auth.getURL(), realm, auth.getKind());
|
||||
((ISVNPersistentAuthenticationProvider) myDelegate).saveAuthentication(auth, kind, realm);
|
||||
myListener.getMulticaster().saveAttemptFinished(ProviderType.persistent, auth.getURL(), realm, auth.getKind());
|
||||
@@ -822,4 +838,16 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im
|
||||
return s[0];
|
||||
}
|
||||
}
|
||||
|
||||
public static class CredentialsSavedException extends RuntimeException {
|
||||
private final boolean mySuccess;
|
||||
|
||||
public CredentialsSavedException(boolean success) {
|
||||
mySuccess = success;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return mySuccess;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
@Override
|
||||
protected boolean onFirstNotification(AuthenticationRequest obj) {
|
||||
if (ProgressManager.getInstance().hasProgressIndicator()) {
|
||||
return ask(obj, null);
|
||||
return ask(obj, null); // TODO
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -247,6 +247,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
|
||||
private SVNURL myWcUrl;
|
||||
private boolean myOutsideCopies;
|
||||
private boolean myForceSaving;
|
||||
|
||||
public AuthenticationRequest(Project project, String kind, SVNURL url, String realm) {
|
||||
myProject = project;
|
||||
@@ -255,6 +256,14 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
|
||||
myRealm = realm;
|
||||
}
|
||||
|
||||
public boolean isForceSaving() {
|
||||
return myForceSaving;
|
||||
}
|
||||
|
||||
public void setForceSaving(boolean forceSaving) {
|
||||
myForceSaving = forceSaving;
|
||||
}
|
||||
|
||||
public boolean isOutsideCopies() {
|
||||
return myOutsideCopies;
|
||||
}
|
||||
|
||||
@@ -259,6 +259,20 @@ public class SvnConfiguration17 implements PersistentStateComponent<Element> {
|
||||
return myOptions;
|
||||
}
|
||||
|
||||
public static SvnAuthenticationManager createForTmpDir(final Project project, final File dir) {
|
||||
final SvnVcs17 vcs = SvnVcs17.getInstance(project);
|
||||
//final SvnAuthenticationManager manager = new SvnAuthenticationManager(project, dir);
|
||||
|
||||
final SvnAuthenticationManager interactive = new SvnAuthenticationManager(project, dir);
|
||||
interactive.setRuntimeStorage(RUNTIME_AUTH_CACHE);
|
||||
final SvnInteractiveAuthenticationProvider interactiveProvider = new SvnInteractiveAuthenticationProvider(vcs, interactive);
|
||||
interactive.setAuthenticationProvider(interactiveProvider);
|
||||
|
||||
//manager.setAuthenticationProvider(new SvnAuthenticationProvider(vcs, interactiveProvider, RUNTIME_AUTH_CACHE));
|
||||
//manager.setRuntimeStorage(RUNTIME_AUTH_CACHE);
|
||||
return interactive;
|
||||
}
|
||||
|
||||
public SvnAuthenticationManager getAuthenticationManager(final SvnVcs17 svnVcs) {
|
||||
if (myAuthManager == null) {
|
||||
// reloaded when configuration directory changes
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn17.auth;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
*/
|
||||
package org.jetbrains.idea.svn17.auth;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
|
||||
import java.util.EventListener;
|
||||
|
||||
@@ -24,4 +26,5 @@ public interface SvnAuthenticationListener extends EventListener {
|
||||
void actualSaveWillBeTried(final ProviderType type, final SVNURL url, String realm, String kind);
|
||||
void saveAttemptStarted(final ProviderType type, final SVNURL url, String realm, String kind);
|
||||
void saveAttemptFinished(final ProviderType type, final SVNURL url, String realm, String kind);
|
||||
void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication);
|
||||
}
|
||||
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 org.jetbrains.idea.svn17.commandLine;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import org.jetbrains.idea.svn17.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn17.SvnConfiguration17;
|
||||
import org.jetbrains.idea.svn17.SvnVcs17;
|
||||
import org.jetbrains.idea.svn17.auth.ProviderType;
|
||||
import org.jetbrains.idea.svn17.auth.SvnAuthenticationListener;
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.SVNAuthentication;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/1/12
|
||||
* Time: 12:28 PM
|
||||
*/
|
||||
public class CommandLineAuthenticator {
|
||||
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn17.commandLine.CommandLineAuthenticator");
|
||||
private final Project myProject;
|
||||
private final AuthenticationRequiringCommand myCommand;
|
||||
private final SvnConfiguration17 myConfiguration17;
|
||||
private final File myConfigDir;
|
||||
|
||||
public CommandLineAuthenticator(Project project, AuthenticationRequiringCommand command) {
|
||||
myProject = project;
|
||||
myCommand = command;
|
||||
myConfiguration17 = SvnConfiguration17.getInstance(project);
|
||||
final String configurationDirectory = myConfiguration17.getConfigurationDirectory();
|
||||
myConfigDir = new File(configurationDirectory);
|
||||
}
|
||||
|
||||
public void doWithAuthentication() throws SVNException {
|
||||
try {
|
||||
myCommand.run(myConfigDir);
|
||||
return;
|
||||
} catch (SVNException e) {
|
||||
if (! e.getErrorMessage().getErrorCode().isAuthentication()) throw e;
|
||||
}
|
||||
File tempDirectory = null;
|
||||
try {
|
||||
tempDirectory = FileUtil.createTempDirectory("tmp", "Subversion");
|
||||
final SvnAuthenticationManager authenticationManager = SvnConfiguration17.createForTmpDir(myProject, tempDirectory);
|
||||
//authenticationManager.setAuthenticationForced(true);
|
||||
authenticationManager.setArtificialSaving(true);
|
||||
myCommand.cleanup();
|
||||
tryGetCredentials(authenticationManager, tempDirectory);
|
||||
|
||||
myCommand.cleanup();
|
||||
myCommand.run(tempDirectory);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
|
||||
} finally {
|
||||
if (tempDirectory != null) {
|
||||
FileUtil.delete(tempDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void tryGetCredentials(SvnAuthenticationManager manager, final File tempDirectory) throws SVNException {
|
||||
final StoreListener storeListener = new StoreListener();
|
||||
manager.addListener(storeListener);
|
||||
final SVNURL svnurl = myCommand.sampleUrl();
|
||||
try {
|
||||
myCommand.runWithSvnkitClient(tempDirectory, manager);
|
||||
LOG.assertTrue(false, "Credentials not asked"); // todo?
|
||||
} catch (SvnAuthenticationManager.CredentialsSavedException e) {
|
||||
// ok, check result?
|
||||
if (e.isSuccess()) {
|
||||
final SvnAuthenticationManager realManager = myConfiguration17.getAuthenticationManager(SvnVcs17.getInstance(myProject));
|
||||
storeListener.reStore(myProject, realManager, svnurl);
|
||||
}
|
||||
}
|
||||
//final SVNWCClient client = new SVNWCClient(manager, myConfiguration17.getOptions(myProject));
|
||||
//client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
|
||||
}
|
||||
|
||||
public interface AuthenticationRequiringCommand {
|
||||
void run(final File configDir) throws SVNException;
|
||||
void runWithSvnkitClient(final File configDir, SvnAuthenticationManager manager) throws SVNException;
|
||||
SVNURL sampleUrl();
|
||||
void cleanup() throws SVNException;
|
||||
}
|
||||
|
||||
private static class StoreListener implements SvnAuthenticationListener {
|
||||
private final Set<StoreData> myData;
|
||||
private final Set<Trinity<String, String, SVNURL>> myAuthRequested;
|
||||
|
||||
private StoreListener() {
|
||||
myData = new HashSet<StoreData>();
|
||||
myAuthRequested = new HashSet<Trinity<String, String, SVNURL>>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requested(ProviderType type, SVNURL url, String realm, String kind, boolean canceled) {
|
||||
if (ProviderType.interactive.equals(type)) {
|
||||
myAuthRequested.add(create(kind, realm, url));
|
||||
}
|
||||
}
|
||||
|
||||
private Trinity<String, String, SVNURL> create(String kind, String realm, SVNURL url) {
|
||||
return new Trinity<String, String, SVNURL>(kind, realm, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actualSaveWillBeTried(ProviderType type, SVNURL url, String realm, String kind) {
|
||||
}
|
||||
@Override
|
||||
public void saveAttemptStarted(ProviderType type, SVNURL url, String realm, String kind) {
|
||||
}
|
||||
@Override
|
||||
public void saveAttemptFinished(ProviderType type, SVNURL url, String realm, String kind) {
|
||||
}
|
||||
@Override
|
||||
public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) {
|
||||
if (accepted && authentication.isStorageAllowed()) {
|
||||
final Trinity<String, String, SVNURL> trinity = create(kind, realm, authentication.getURL());
|
||||
if (myAuthRequested.contains(trinity)) {
|
||||
myData.add(new StoreData(kind, realm, authentication));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reStore(final Project project, final SvnAuthenticationManager realManager, final SVNURL svnurl) {
|
||||
for (StoreData data : myData) {
|
||||
if (data.myAuthentication == null) continue;
|
||||
realManager.requested(ProviderType.interactive, svnurl, data.myRealm, data.myKind, false);
|
||||
try {
|
||||
realManager.acknowledgeAuthentication(true, data.myKind, data.myRealm, null, data.myAuthentication);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(project, "Wasn't able to store credentials: " + e.getMessage(), MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class StoreData {
|
||||
public String myKind;
|
||||
public String myRealm;
|
||||
public SVNAuthentication myAuthentication;
|
||||
|
||||
private StoreData(String kind, String realm, SVNAuthentication authentication) {
|
||||
myKind = kind;
|
||||
myRealm = realm;
|
||||
myAuthentication = authentication;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
StoreData data = (StoreData)o;
|
||||
|
||||
if (myKind != null ? !myKind.equals(data.myKind) : data.myKind != null) return false;
|
||||
if (myRealm != null ? !myRealm.equals(data.myRealm) : data.myRealm != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = myKind != null ? myKind.hashCode() : 0;
|
||||
result = 31 * result + (myRealm != null ? myRealm.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
+270
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 org.jetbrains.idea.svn17.commandLine;
|
||||
|
||||
import com.intellij.execution.process.ProcessOutputTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vcs.LineProcessEventListener;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import org.jetbrains.idea.svn17.SvnAuthenticationManager;
|
||||
import org.jetbrains.idea.svn17.SvnConfiguration17;
|
||||
import org.jetbrains.idea.svn17.SvnVcs17;
|
||||
import org.jetbrains.idea.svn17.portable.SvnExceptionWrapper;
|
||||
import org.jetbrains.idea.svn17.portable.SvnSvnkitUpdateClient;
|
||||
import org.tmatesoft.svn.core.*;
|
||||
import org.tmatesoft.svn.core.wc.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/1/12
|
||||
* Time: 12:13 PM
|
||||
*/
|
||||
public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
|
||||
private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+");
|
||||
private static final String ourAuthenticationRealm = "Authentication realm:";
|
||||
private final Project myProject;
|
||||
private final VirtualFile myCommonAncestor;
|
||||
|
||||
public SvnCommandLineUpdateClient(final Project project, VirtualFile commonAncestor) {
|
||||
super(SvnVcs17.getInstance(project).createUpdateClient());
|
||||
myProject = project;
|
||||
myCommonAncestor = commonAncestor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), false, false, false);
|
||||
return longs[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException {
|
||||
final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), force, false, false);
|
||||
return longs[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
|
||||
throws SVNException {
|
||||
return doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions,
|
||||
final boolean depthIsSticky, final boolean makeParents) throws SVNException {
|
||||
// since one revision is passed -> I assume same repository here
|
||||
final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myProject);
|
||||
final SVNInfo info = infoClient.doInfo(paths[0], SVNRevision.UNDEFINED);
|
||||
if (info == null || info.getURL() == null) {
|
||||
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, paths[0].getPath()));
|
||||
}
|
||||
final long[] result = new long[paths.length];
|
||||
|
||||
new CommandLineAuthenticator(myProject, new CommandLineAuthenticator.AuthenticationRequiringCommand() {
|
||||
@Override
|
||||
public void run(File configDir) throws SVNException {
|
||||
final File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath());
|
||||
final SvnLineCommand command = new SvnLineCommand(myProject, base, SvnCommandName.up);
|
||||
if (revision != null && ! SVNRevision.UNDEFINED.equals(revision) && ! SVNRevision.WORKING.equals(revision)) {
|
||||
command.addParameters("-r", revision.toString());
|
||||
}
|
||||
// unknown depth is not used any more for 1.7 -> why?
|
||||
if (depth != null && ! SVNDepth.UNKNOWN.equals(depth)) {
|
||||
command.addParameters("--depth", depth.toString());
|
||||
}
|
||||
if (allowUnversionedObstructions) {
|
||||
command.addParameters("--force");
|
||||
}
|
||||
if (depthIsSticky && depth != null) {// !!! not sure, but not used
|
||||
command.addParameters("--set-depth", depth.toString());
|
||||
}
|
||||
if (makeParents) {
|
||||
command.addParameters("--parents");
|
||||
}
|
||||
command.addParameters("--accept", "postpone");
|
||||
command.addParameters("--config-dir", configDir.getPath());
|
||||
|
||||
for (File path : paths) {
|
||||
command.addParameters(path.getPath());
|
||||
}
|
||||
|
||||
final StringBuffer sbError = new StringBuffer();
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
final ISVNEventHandler handler = getEventHandler();
|
||||
final UpdateOutputLineConverter converter = new UpdateOutputLineConverter(base);
|
||||
final SVNException[] innerException = new SVNException[1];
|
||||
command.addListener(new LineProcessEventListener() {
|
||||
@Override
|
||||
public void onLineAvailable(String line, Key outputType) {
|
||||
if (ProcessOutputTypes.STDOUT.equals(outputType)) {
|
||||
final SVNEvent event = converter.convert(line);
|
||||
if (event != null) {
|
||||
checkForUpdateCompleted(event);
|
||||
try {
|
||||
handler.handleEvent(event, 0.5);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
command.cancel();
|
||||
semaphore.up();
|
||||
innerException[0] = e;
|
||||
}
|
||||
}
|
||||
} else if (ProcessOutputTypes.STDERR.equals(outputType)) {
|
||||
sbError.append(line);
|
||||
if (line.contains(ourAuthenticationRealm)) {
|
||||
command.cancel();
|
||||
semaphore.up();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processTerminated(int exitCode) {
|
||||
semaphore.up();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startFailed(Throwable exception) {
|
||||
semaphore.up();
|
||||
}
|
||||
});
|
||||
try {
|
||||
command.start();
|
||||
semaphore.waitFor();
|
||||
|
||||
checkForException(sbError);
|
||||
} catch (SvnExceptionWrapper e){
|
||||
throw (SVNException) e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runWithSvnkitClient(File configDir, SvnAuthenticationManager manager) throws SVNException {
|
||||
final SVNUpdateClient client = new SVNUpdateClient(manager, SvnConfiguration17.getInstance(myProject).getOptions(myProject));
|
||||
client.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
|
||||
}
|
||||
|
||||
private void checkForUpdateCompleted(SVNEvent event) {
|
||||
if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) {
|
||||
final long eventRevision = event.getRevision();
|
||||
for (int i = 0; i < paths.length; i++) {
|
||||
final File path = paths[i];
|
||||
if (path.equals(event.getFile())) {
|
||||
result[i] = eventRevision;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SVNURL sampleUrl() {
|
||||
return info.getURL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() throws SVNException {
|
||||
final SvnVcs17 vcs17 = SvnVcs17.getInstance(myProject);
|
||||
final SVNWCClient client = vcs17.createWCClient();
|
||||
for (File path : paths) {
|
||||
client.doCleanup(path);
|
||||
}
|
||||
}
|
||||
}).doWithAuthentication();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void checkForException(final StringBuffer sbError) throws SVNException {
|
||||
if (sbError.length() == 0) return;
|
||||
final String message = sbError.toString();
|
||||
final Matcher matcher = ourExceptionPattern.matcher(message);
|
||||
if (matcher.matches()) {
|
||||
final String group = matcher.group(1);
|
||||
if (group != null) {
|
||||
try {
|
||||
final int code = Integer.parseInt(group);
|
||||
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message));
|
||||
} catch (NumberFormatException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message.contains(ourAuthenticationRealm)) {
|
||||
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message));
|
||||
}
|
||||
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
|
||||
throws SVNException {
|
||||
final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false);
|
||||
return longs[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
throw new UnsupportedOperationException();
|
||||
//return super.doSwitch(file, url, revision, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
throw new UnsupportedOperationException();
|
||||
//return super.doSwitch(file, url, pegRevision, revision, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
|
||||
throws SVNException {
|
||||
throw new UnsupportedOperationException();
|
||||
//return super.doSwitch(file, url, pegRevision, revision, recursive, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File path,
|
||||
SVNURL url,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions,
|
||||
boolean depthIsSticky) throws SVNException {
|
||||
throw new UnsupportedOperationException();
|
||||
//return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File path,
|
||||
SVNURL url,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions,
|
||||
boolean depthIsSticky,
|
||||
boolean ignoreAncestry) throws SVNException {
|
||||
throw new UnsupportedOperationException();
|
||||
// todo MAIN
|
||||
//return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
|
||||
}
|
||||
}
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 org.jetbrains.idea.svn17.commandLine;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.tmatesoft.svn.core.SVNErrorCode;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNNodeKind;
|
||||
import org.tmatesoft.svn.core.wc.SVNEvent;
|
||||
import org.tmatesoft.svn.core.wc.SVNEventAction;
|
||||
import org.tmatesoft.svn.core.wc.SVNStatusType;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/1/12
|
||||
* Time: 5:13 PM
|
||||
*/
|
||||
public class UpdateOutputLineConverter {
|
||||
private final static String UPDATING = "Updating";
|
||||
private final static String AT_REVISION = "At revision (\\d+)\\.";
|
||||
private final static String UPDATED_TO_REVISION = "Updated to revision (\\d+)\\.";
|
||||
private final static String SKIPPED = "Skipped";
|
||||
private final static String RESTORED = "Restored";
|
||||
|
||||
private final static String FETCHING_EXTERNAL = "Fetching external";
|
||||
private final static String EXTERNAL = "External at (\\d+)\\.";
|
||||
private final static String UPDATED_EXTERNAL = "Updated external to revision (\\d+)\\.";
|
||||
|
||||
private final static Pattern ourAtRevision = Pattern.compile(AT_REVISION);
|
||||
private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION);
|
||||
|
||||
private final static Pattern ourExternal = Pattern.compile(EXTERNAL);
|
||||
private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL);
|
||||
|
||||
private final static Pattern[] ourCompletePatterns = new Pattern[] {ourAtRevision, ourUpdatedToRevision, ourExternal, ourUpdatedExternal};
|
||||
|
||||
private final File myBase;
|
||||
private File myCurrentFile;
|
||||
|
||||
public UpdateOutputLineConverter(File base) {
|
||||
myBase = base;
|
||||
}
|
||||
|
||||
public SVNEvent convert(final String line) {
|
||||
if (StringUtil.isEmptyOrSpaces(line)) return null;
|
||||
|
||||
if (line.startsWith(UPDATING)) {
|
||||
myCurrentFile = parseForPath(line);
|
||||
return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE),
|
||||
null, -1, null, null, null, null, SVNEventAction.UPDATE_NONE, SVNEventAction.UPDATE_NONE, null, null, null, null, null);
|
||||
} else if (line.startsWith(RESTORED)) {
|
||||
myCurrentFile = parseForPath(line);
|
||||
return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE),
|
||||
null, -1, null, null, null, null, SVNEventAction.RESTORE, SVNEventAction.RESTORE, null, null, null, null, null);
|
||||
} else if (line.startsWith(SKIPPED)) {
|
||||
myCurrentFile = parseForPath(line);
|
||||
final String comment = parseComment(line);
|
||||
return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE),
|
||||
null, -1, null, null, null, null, SVNEventAction.SKIP, SVNEventAction.SKIP,
|
||||
comment == null ? null : SVNErrorMessage.create(SVNErrorCode.WC_OBSTRUCTED_UPDATE, comment), null, null, null, null);
|
||||
} else if (line.startsWith(FETCHING_EXTERNAL)) {
|
||||
myCurrentFile = parseForPath(line);
|
||||
return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE),
|
||||
null, -1, null, null, null, null, SVNEventAction.UPDATE_EXTERNAL, SVNEventAction.UPDATE_EXTERNAL, null, null, null, null, null);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ourCompletePatterns.length; i++) {
|
||||
final Pattern pattern = ourCompletePatterns[i];
|
||||
final long revision = matchAndGetRevision(pattern, line);
|
||||
if (revision != -1) {
|
||||
return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE),
|
||||
null, revision, null, null, null, null, SVNEventAction.UPDATE_COMPLETED, SVNEventAction.UPDATE_COMPLETED, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
return parseNormalString(line);
|
||||
}
|
||||
|
||||
private final static Set<Character> ourActions = new HashSet<Character>(Arrays.asList(new Character[] {'A', 'D', 'U', 'C', 'G', 'E', 'R'}));
|
||||
|
||||
@Nullable
|
||||
private SVNEvent parseNormalString(final String line) {
|
||||
if (line.length() < 5) return null;
|
||||
final char first = line.charAt(0);
|
||||
if (' ' != first && ! ourActions.contains(first)) return null;
|
||||
final SVNStatusType contentsStatus = getStatusType(first);
|
||||
final char second = line.charAt(1);
|
||||
final SVNStatusType propertiesStatus = getStatusType(second);
|
||||
final char lock = line.charAt(2); // dont know what to do with stolen lock info
|
||||
if (' ' != lock && 'B' != lock) return null;
|
||||
final char treeConflict = line.charAt(3);
|
||||
if (' ' != treeConflict && 'C' != treeConflict) return null;
|
||||
final boolean haveTreeConflict = 'C' == treeConflict;
|
||||
|
||||
final String path = line.substring(4).trim();
|
||||
if (StringUtil.isEmptyOrSpaces(path)) return null;
|
||||
final File file = new File(myBase, path);
|
||||
if (SVNStatusType.STATUS_OBSTRUCTED.equals(contentsStatus)) {
|
||||
// obstructed
|
||||
return new SVNEvent(file, file.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE,
|
||||
null, -1, contentsStatus, propertiesStatus, null, null, SVNEventAction.UPDATE_SKIP_OBSTRUCTION, SVNEventAction.UPDATE_ADD,
|
||||
null, null, null, null, null);
|
||||
}
|
||||
|
||||
SVNEventAction action;
|
||||
SVNEventAction expectedAction;
|
||||
if (SVNStatusType.STATUS_ADDED.equals(contentsStatus)) {
|
||||
expectedAction = SVNEventAction.UPDATE_ADD;
|
||||
} else if (SVNStatusType.STATUS_DELETED.equals(contentsStatus)) {
|
||||
expectedAction = SVNEventAction.UPDATE_DELETE;
|
||||
} else {
|
||||
expectedAction = SVNEventAction.UPDATE_UPDATE;
|
||||
}
|
||||
action = expectedAction;
|
||||
if (haveTreeConflict) {
|
||||
action = SVNEventAction.TREE_CONFLICT;
|
||||
}
|
||||
|
||||
return new SVNEvent(file, file.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE, null, -1, contentsStatus, propertiesStatus, null,
|
||||
null, action, expectedAction, null, null, null, null, null);
|
||||
}
|
||||
|
||||
private SVNStatusType getStatusType(char first) {
|
||||
final SVNStatusType contentsStatus;
|
||||
if ('A' == first) {
|
||||
contentsStatus = SVNStatusType.STATUS_ADDED;
|
||||
} else if ('D' == first) {
|
||||
contentsStatus = SVNStatusType.STATUS_DELETED;
|
||||
} else if ('U' == first) {
|
||||
contentsStatus = SVNStatusType.CHANGED;
|
||||
} else if ('C' == first) {
|
||||
contentsStatus = SVNStatusType.CONFLICTED;
|
||||
} else if ('G' == first) {
|
||||
contentsStatus = SVNStatusType.MERGED;
|
||||
} else if ('R' == first) {
|
||||
contentsStatus = SVNStatusType.STATUS_REPLACED;
|
||||
} else if ('E' == first) {
|
||||
contentsStatus = SVNStatusType.STATUS_OBSTRUCTED;
|
||||
} else {
|
||||
contentsStatus = SVNStatusType.STATUS_NORMAL;
|
||||
}
|
||||
return contentsStatus;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private long matchAndGetRevision(final Pattern pattern, final String line) {
|
||||
final Matcher matcher = pattern.matcher(line);
|
||||
if (matcher.matches()) {
|
||||
final String group = matcher.group(1);
|
||||
if (group == null) return -1;
|
||||
try {
|
||||
return Long.parseLong(group);
|
||||
} catch (NumberFormatException e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String parseComment(final String line) {
|
||||
final int idx = line.lastIndexOf("--");
|
||||
if (idx != -1 && idx < (line.length() - 2)) {
|
||||
return line.substring(idx + 2).trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private File parseForPath(final String line) {
|
||||
final int idx1 = line.indexOf('\'');
|
||||
if (idx1 == -1) return null;
|
||||
final int idx2 = line.indexOf('\'', idx1 + 1);
|
||||
if (idx2 == -1) return null;
|
||||
final String substring = line.substring(idx1 + 1, idx2);
|
||||
if (".".equals(substring)) return myBase;
|
||||
return new File(myBase, substring);
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,14 @@ package org.jetbrains.idea.svn17.dialogs;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.idea.svn17.SvnAuthenticationNotifier;
|
||||
import org.jetbrains.idea.svn17.SvnConfiguration17;
|
||||
import org.jetbrains.idea.svn17.SvnVcs17;
|
||||
import org.tmatesoft.svn.core.SVNErrorMessage;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
|
||||
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
|
||||
@@ -40,11 +43,13 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider {
|
||||
private final Project myProject;
|
||||
private final SvnAuthenticationNotifier myAuthenticationNotifier;
|
||||
private final ISVNAuthenticationProvider mySvnInteractiveAuthenticationProvider;
|
||||
private final SvnVcs17 mySvnVcs;
|
||||
private final ISVNAuthenticationStorage myAuthenticationStorage;
|
||||
private static final Set<Thread> ourForceInteractive = new HashSet<Thread>();
|
||||
|
||||
public SvnAuthenticationProvider(final SvnVcs17 svnVcs, final ISVNAuthenticationProvider provider,
|
||||
final ISVNAuthenticationStorage authenticationStorage) {
|
||||
mySvnVcs = svnVcs;
|
||||
myAuthenticationStorage = authenticationStorage;
|
||||
myProject = svnVcs.getProject();
|
||||
myAuthenticationNotifier = svnVcs.getAuthNotifier();
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 org.jetbrains.idea.svn17.portable;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/1/12
|
||||
* Time: 12:11 PM
|
||||
*/
|
||||
public class SvnSvnkitUpdateClient implements SvnUpdateClientI {
|
||||
private final SVNUpdateClient myClient;
|
||||
private ISVNEventHandler myDispatcher;
|
||||
|
||||
public SvnSvnkitUpdateClient(SVNUpdateClient client) {
|
||||
myClient = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
return myClient.doUpdate(file, revision, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException {
|
||||
return myClient.doUpdate(file, revision, recursive, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] doUpdate(File[] paths,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions,
|
||||
boolean depthIsSticky) throws SVNException {
|
||||
return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] doUpdate(File[] paths,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions,
|
||||
boolean depthIsSticky,
|
||||
boolean makeParents) throws SVNException {
|
||||
return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky)
|
||||
throws SVNException {
|
||||
return myClient.doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUpdateLocksOnDemand(boolean locksOnDemand) {
|
||||
myClient.setUpdateLocksOnDemand(locksOnDemand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
return myClient.doSwitch(file, url, revision, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
return myClient.doSwitch(file, url, pegRevision, revision, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
|
||||
throws SVNException {
|
||||
return myClient.doSwitch(file, url, pegRevision, revision, recursive, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File path,
|
||||
SVNURL url,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException {
|
||||
return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doSwitch(File path,
|
||||
SVNURL url,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException {
|
||||
return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException {
|
||||
return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force)
|
||||
throws SVNException {
|
||||
return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive, force);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doCheckout(SVNURL url,
|
||||
File dstPath,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
SVNDepth depth,
|
||||
boolean allowUnversionedObstructions) throws SVNException {
|
||||
return myClient.doCheckout(url, dstPath, pegRevision, revision, depth, allowUnversionedObstructions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doExport(SVNURL url,
|
||||
File dstPath,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
String eolStyle,
|
||||
boolean force,
|
||||
boolean recursive) throws SVNException {
|
||||
return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doExport(SVNURL url,
|
||||
File dstPath,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
String eolStyle,
|
||||
boolean overwrite,
|
||||
SVNDepth depth) throws SVNException {
|
||||
return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, overwrite, depth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doExport(File srcPath,
|
||||
File dstPath,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
String eolStyle,
|
||||
boolean force,
|
||||
boolean recursive) throws SVNException {
|
||||
return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, force, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long doExport(File srcPath,
|
||||
File dstPath,
|
||||
SVNRevision pegRevision,
|
||||
SVNRevision revision,
|
||||
String eolStyle,
|
||||
boolean overwrite,
|
||||
SVNDepth depth) throws SVNException {
|
||||
return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, overwrite, depth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException {
|
||||
myClient.doRelocate(dst, oldURL, newURL, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException {
|
||||
myClient.doCanonicalizeURLs(dst, omitDefaultPort, recursive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExportExpandsKeywords(boolean expand) {
|
||||
myClient.setExportExpandsKeywords(expand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEventHandler(ISVNEventHandler dispatcher) {
|
||||
myDispatcher = dispatcher;
|
||||
myClient.setEventHandler(dispatcher);
|
||||
}
|
||||
|
||||
public ISVNEventHandler getEventHandler() {
|
||||
return myDispatcher;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 org.jetbrains.idea.svn17.portable;
|
||||
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Irina.Chernushina
|
||||
* Date: 2/1/12
|
||||
* Time: 11:59 AM
|
||||
*/
|
||||
public interface SvnUpdateClientI {
|
||||
long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException;
|
||||
|
||||
long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
|
||||
|
||||
long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
|
||||
|
||||
long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException;
|
||||
|
||||
long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
|
||||
|
||||
void setUpdateLocksOnDemand(boolean locksOnDemand);
|
||||
|
||||
long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException;
|
||||
|
||||
long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException;
|
||||
|
||||
long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
|
||||
|
||||
long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException;
|
||||
|
||||
long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException;
|
||||
|
||||
long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException;
|
||||
|
||||
long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException;
|
||||
|
||||
long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions) throws SVNException;
|
||||
|
||||
long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException;
|
||||
|
||||
long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException;
|
||||
|
||||
long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException;
|
||||
|
||||
long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException;
|
||||
|
||||
void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException;
|
||||
|
||||
void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException;
|
||||
|
||||
void setExportExpandsKeywords(boolean expand);
|
||||
void setEventHandler(ISVNEventHandler dispatcher);
|
||||
}
|
||||
@@ -23,10 +23,10 @@ import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.update.UpdatedFiles;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn17.SvnBundle;
|
||||
import org.jetbrains.idea.svn17.SvnConfiguration17;
|
||||
import org.jetbrains.idea.svn17.SvnRevisionNumber;
|
||||
import org.jetbrains.idea.svn17.SvnVcs17;
|
||||
import org.jetbrains.idea.svn17.*;
|
||||
import org.jetbrains.idea.svn17.commandLine.SvnCommandLineUpdateClient;
|
||||
import org.jetbrains.idea.svn17.portable.SvnSvnkitUpdateClient;
|
||||
import org.jetbrains.idea.svn17.portable.SvnUpdateClientI;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
@@ -82,25 +82,16 @@ public class SvnUpdateEnvironment17 extends AbstractSvnUpdateIntegrateEnvironmen
|
||||
final SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myVcs.getProject());
|
||||
final UpdateRootInfo rootInfo = configuration.getUpdateRootInfo(root, myVcs);
|
||||
|
||||
final SVNUpdateClient updateClient = myVcs.createUpdateClient();
|
||||
updateClient.setEventHandler(myHandler);
|
||||
updateClient.setUpdateLocksOnDemand(configuration.UPDATE_LOCK_ON_DEMAND);
|
||||
if (rootInfo != null) {
|
||||
final SVNURL url = rootInfo.getUrl();
|
||||
if (url != null && url.equals(getSourceUrl(myVcs, root))) {
|
||||
if (rootInfo.isUpdateToRevision()) {
|
||||
rev = updateClient.doUpdate(root, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
} else {
|
||||
rev = updateClient.doUpdate(root, SVNRevision.HEAD, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
}
|
||||
final SVNURL sourceUrl = getSourceUrl(myVcs, root);
|
||||
final boolean isSwitch = rootInfo != null && rootInfo.getUrl() != null && ! rootInfo.getUrl().equals(sourceUrl);
|
||||
final SVNRevision updateTo = rootInfo != null && rootInfo.isUpdateToRevision() ? rootInfo.getRevision() : SVNRevision.HEAD;
|
||||
|
||||
} else if (url != null) {
|
||||
rev = updateClient.doSwitch(root, url, SVNRevision.UNDEFINED, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
} else {
|
||||
rev = updateClient.doUpdate(root, SVNRevision.HEAD, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
}
|
||||
if (isSwitch) {
|
||||
final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, true, sourceUrl);
|
||||
rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
} else {
|
||||
rev = updateClient.doUpdate(root, SVNRevision.HEAD, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, false, sourceUrl);
|
||||
rev = updateClient.doUpdate(root, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false);
|
||||
}
|
||||
|
||||
myPostUpdateFiles.setRevisions(root.getAbsolutePath(), myVcs, new SvnRevisionNumber(SVNRevision.create(rev)));
|
||||
@@ -108,6 +99,20 @@ public class SvnUpdateEnvironment17 extends AbstractSvnUpdateIntegrateEnvironmen
|
||||
return rev;
|
||||
}
|
||||
|
||||
private SvnUpdateClientI createUpdateClient(SvnConfiguration17 configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
|
||||
final SvnUpdateClientI updateClient;
|
||||
// do not do from command line for switch now
|
||||
if (! isSwitch && SvnConfiguration17.UseAcceleration.commandLine.equals(configuration.myUseAcceleration) &&
|
||||
Svn17Detector.is17(myVcs.getProject(), root) && SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol())) {
|
||||
updateClient = new SvnCommandLineUpdateClient(myVcs.getProject(), null);
|
||||
} else {
|
||||
updateClient = new SvnSvnkitUpdateClient(myVcs.createUpdateClient());
|
||||
}
|
||||
updateClient.setEventHandler(myHandler);
|
||||
updateClient.setUpdateLocksOnDemand(configuration.UPDATE_LOCK_ON_DEMAND);
|
||||
return updateClient;
|
||||
}
|
||||
|
||||
protected boolean isMerge() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1054,6 +1054,10 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
return myCnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAttemptStarted(ProviderType type, SVNURL url, String realm, String kind) {
|
||||
mySaved = false;
|
||||
@@ -1119,6 +1123,10 @@ public class SvnAuthenticationTest extends PlatformTestCase {
|
||||
mySaved = new HashSet<Pair<SVNURL, String>>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mySaved.clear();
|
||||
myClientRequested.clear();
|
||||
|
||||
Reference in New Issue
Block a user