SVN 1.7: command line client - to be used for update (not switch) + http protocol

This commit is contained in:
irengrig
2012-02-07 13:08:52 +04:00
parent aa82cbdb36
commit dc1b51d7ce
14 changed files with 1057 additions and 27 deletions
@@ -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);
}
@@ -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;
}
}
}
@@ -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);
}
}
@@ -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();